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

Peter Verhas peter at verhas.com
2011. Ápr. 12., K, 10:35:35 CEST


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

--------- következő rész ---------
Egy csatolt HTML állomány át lett konvertálva...
URL: http://javagrund.hu/pipermail/javalist/attachments/20110412/07fb64b1/attachment-0001.html 
--------- következő rész ---------
Egy nem text típusú csatolt állomány át lett konvertálva...
Név: smime.p7s
Típus: application/pkcs7-signature
Méret: 6739 bytes
Leírás: nem elérhető
Url : http://javagrund.hu/pipermail/javalist/attachments/20110412/07fb64b1/attachment-0001.bin 


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