[Java lista] JPA - Hogyan inzertáljak egy-több kapcsolatban lév? adatokat?

istvan.ketler at lhsystems.com istvan.ketler at lhsystems.com
2011. Ápr. 12., K, 13:17:15 CEST


Szia,

 

miért kavartad volna meg?

 

Az optimalizálás legfőbb szabálya az, hogy soha ne optimalizálj. Ha mégis optimalizálni akarsz, elsőként környezetet vizsgálj (csak mert Commodore 64-en lassú, még lehet elfogadható sebességű egy OS 360-on, mondták az öregek). Ha még mindig lassú, mérj. Ha mértél, nézd meg hogy lehet-e algoritmust vagy technológiát váltani ott, ahol sok időt tölt. Ha nem lehet, vagy az nem elég, akkor kezdj el azon gondolkodni, hogy mit lenne célszerű optimalizálni. Kis lépésekben tedd, és mindegyik után mérj.

 

Még ma is találkozom néha C-like nyelven fejlesztővel, aki szerint a ++i gyorsabb mint az i++...

István Ketler
Team Leader 

Lufthansa Systems Hungaria Kft. 
Airline Management Solutions 
- Schedule & Revenue Management 
- Business Intelligence & Database Solutions
Neumann János u. 1/e
1117 Budapest
Hungary 

Tel: +36 1 887-2815 
Fax: +36 1 887-2977
Mobile: +36 30 600-4936 

Room: Infopark E, Room LH1-31 

e-mail: istvan.ketler at lhsystems.com 
Internet: www.LHsystems.hu <http://www.lhsystems.hu/> 

 

From: javalist-bounces at javagrund.hu [mailto:javalist-bounces at javagrund.hu] On Behalf Of Peter Verhas
Sent: Tuesday, April 12, 2011 10:36 AM
To: javalist at javagrund.hu
Subject: Re: [Java lista] JPA - Hogyan inzertáljak egy-több kapcsolatban lév? adatokat?

 

Szerintem Zsombornál van a pont.

 

Mi történhet, amikor létrehozod az új Group csoportot, beállítod a GroupId-t, és utána a User objetkumot perzisztálod? A perzisztencia réteg nem feltétlenül ellenőrzi, hogy van-e már ilyen GroupId a táblában, és nem olvassa fel (ezt akarod éppen performancia okok miatt elkerülni, és lehet, hogy sikerül is). Ellenben amikor legközelebb kell neked ez a Group objektum, akkor tudni fogja, hogy hoppá: ez már itt van a memóriában. És nem olvassa fel, hiszen tőled már megkapta.

 

Nem tudom pontosan, hogy mi történik a programodban, de a JPA objektum státuszokat kellene alaposan átolvasni és megérteni, ha tudni akarod, hogy mi történik, és miért null értékűek a mezők. Ha nem akarod ennyire részletesen megérteni, akkor (azon túl, hogy legközelebb más hibába fogsz belefutni a megértés hiánya miatt) kövesd Zsombor tanácsát.

 

Amúgy egy általános javaslat, sok év tapasztalata alapján:

 

Nem optimalizálunk a részletekben, amikor fejlesztünk. Ha hatékony kódot akarsz készíteni, akkor a következőket javaslom:

 

- Tervezéskor hatékony algoritmust válassz. (nem implementációt, hanem algoritmust)

- Kódolásnál írjál tiszta és szép kódot. Majd a fordító optimalizál amit tud, és ma már elég sokat tudnak.

- Ha lassú, akkor profiler. Ne próbáld magad okosságból kitalálni, hogy hol lassú. Úgysem ott lesz lassú, ahol gondolod. Majd a profiler megmondja.

- Azt a részt optimalizáld amelyik lassú.

- Csak akkor optimalizálj ha üzletileg megéri, mert az optimalizált kód sokszor bonyolultabb, és ezért kevésbé karbantartható, később többe kerül.

 

Attól félek ezzel megint megkavartam az állóvizet :-)

 

--
Verhás Péter
peter at verhas.com
+36(30)9306805
skype: verhas

 





 

On 2011.04.12., at 0:24, Zsombor wrote:





 

2011/4/11 Mariák Kálmán <sirkalmi at kalmiesemese.hu>

Szervusztok!

Egy-több kapcsolatban lévő adatok inzertálására van egy bevett
eljárásom, amivel kapcsolatban problámák adódtak. Ezt az eljárást sehol
nem olvastam, magam találtam ki, ezért lehet, hogy tök rosz az egész.
Elsőként bemutatom az eljárásomat, aztán arra volnék kiváncsi, hogy ti
hogyan oldjátok meg ezeket a dolgokat.

Példa:
Egy felhasználót hozzáadunk egy csoporthoz. A felhasználó és a csoport
azonosítók paraméterből jönnek. A felhasználót az azonosítója alapján
elkérem az EntityManager-től. Eddig semmi szokatlan. A csoport esetében
viszont az entitásokat én példányosítom, amelynek csak az id
tulajdonságát állítom be. Ez pont elég ahoz, hogy ez alapján a
kapcsolatokat megfelelően le tudja tárolni az adatbázisban.

User user = em.find(User.class, userId);
Set<Group> groups = new HashSet<Group>();
Group group = new Group();
group.setId(groupId);
user.setGroups(groups);
em.merge(user);

Ezt anno azért találtam így ki, hogy takarékoskodjak az erőforrásokkal,
és hogy ne kelljen értelmetlenül az adatbázishoz fordulni, mikor eleve
minden információ rendelkezésre áll amit le kell tárolni. Ugyanakkor
kényelmes is amit az alábbi példában szemléltetek:

A User entitásnál maradva, annak van egy CompanyType típusú
tulajdonsága. Ha a company type szintén paraméterből jön akkor azt a
User entitás setCompanyTypeId metódussal állítom be, amiben
példányosítok egy CompanyType objektumot, majd meghívom vele a
setCompanyType metódust, ezzel beállítva a kapcsolatot.

Az alap settter metódus.
public void setCompanyType(CompanyType companyType) {
 this.companyType = companyType;
}

A "kényelmi" kiegészítő setter metódus
public void setCompanyTypeId(Long companyTypeId) {
 CompanyType companyType = new CompanyType();
 companyType.setId(companyTypeId);
 setCompanyType(companyType);
}

A paraméterek rendszerint JSON fromátumban érkeznek, amit a Jackson nevű
eszköz mappel rá az entitásokra. A paraméterek nevei alapján
automatikusan meghívja a setter metódusokat. Pl a fenti példában, ha a
JSON-ban van egy companyTypeId paraméter akkor a Jackson meghívja a
setCompanyTypeId metódust.

A probláma ezzel az egésszel az, hogy persist vagy merge után a program
egy egészen más pontján, pl egy JPQL lekérdezés során visszaadott
eredményben, ha szerepelnek ezek az entitások melyek, így én álltalam
lettek példányosítva, akkor ezeknek a tulajdonsági mind null-ok lesznek
az id-t leszámítva. Ezen csak egy webapp restart segít, mikor
valószínűleg kiürül az Entit Manager -ben a cache és újból beolvas
mindent.

Egyelőre két megoldást látok, vagy felhagyok ezzel a megoldással és
mindig minden entitást id alapján elkérek az EM-től és ezeket állítom
be, vagy lekérdezésekkor ellenőrzöm, hogy adott tulajdonság null-e és,
ha igen akkor meghívom az adott entitásra az EM update metódusát, amely
frissíti az adatbázisból az összes tulajdonságát.

Mind a két megoldás macera, nem tetszik. Mitévő legyek?

Köszi a válaszokat!

Mariák Kálmán
sirkalmi



Egy enitityManager.find(cls, id) hivás nem feltétlenül jelent adatbázis lekérdezést, és használd azt, ne próbáld meg megerőszakolni a JPA implementációt ilyen kis trükkökkel. 

üdv
 Zs


_______________________________________________
Javalist mailing list
Javalist at javagrund.hu
http://javagrund.hu/mailman/listinfo/javalist

 


 
Sitz der Gesellschaft / Corporate Headquarters: Lufthansa Systems Hungaria Kft, Budapest, Fövarosi Birosag 01-09-463417
Geschaeftsfuehrung / Management Board: Monika Houck


--------- következő rész ---------
Egy csatolt HTML állomány át lett konvertálva...
URL: http://javagrund.hu/pipermail/javalist/attachments/20110412/89178d72/attachment-0001.html 


További információk a(z) Javalist levelezőlistáról