JPA unidirectional kapcsolat probléma

Keresés
Hírlevél
 
ASPC#C++CSSDelphiFlashJavaJavaScriptPascalPerlPHPPythonuniPaaSVisual BasicVisual C++  »    
nyitotta: j_java, idő: 2012.07.09., moderátor: moderator
  Értesítés változás esetén Felvétel kedvencekhez Küldés emailben

Kategóriák:Web-programozás » J2EE
Programozási nyelvek » Java

Sorrend:
Időzóna:
Blokkméret:
Oszd meg!
Sziasztok!
A következő problémám van.
Van 3 osztály (a példa kedvéért), Autó, Kerék, Csavar. Az autónak vannak kerekei, a keréknek csavarjai (3 szintű tartalmazás)

JPA unidirectional kapcsolat van közöttük. Az Autóban kerékList, a kerékben csavarList


Autó.java

@OneToMany(targetEntity=Kerek.class ,cascade=CascadeType.ALL,orphanRemoval=true) @JoinColumn(name="AUTO_ID" ,referencedColumnName= "ID" )
private List<Kerek> kerekList= new ArrayList<Kerek>();

Kerek.java

@OneToMany(targetEntity=Csavar.class ,cascade=CascadeType.ALL,orphanRemoval=true) @JoinColumn(name="KEREK_ID" ,referencedColumnName= "ID" )
private List<Csavar> csavarList = new ArrayList<Csavar>();

Mivel unidirectional, ezért a tartalmazott osztályban nincs referencia a tartalmazó osztályra.
És a probléma.

Auto auto=new auto();
em.persist (auto) // itt még jó

Kerek kerek= new Kerek();
auto.getKerekList().add(kerek);
Csavar csavar=new Csavar();
kerek.getCsavarList().add(csavar);

em.merge(auto);//itt azt várnám, hogy az újonnan kapott listaelemeket, adott listaelemeket lementse.


Lementi, de a kerek-ben az AUTO_ID null, az auto id-ja helyett.
Tudjátok hogy miért van?
UI: bidirectional relationshippel, mindkét oldalról a relációt beállítva helyesen működik, jól kitölti az auto_id-t. undirectionalnál miért nem?

Előre is koszi a segítséget!
Szia,

elsőre logikailag van bukfenc a dologban: a Many oldalon akarod a kapcsolatot tárolni úgy, hogy a Many oldal nem tudhat arról, hogy kihez tartozik?

Mivel egyirányú a kapcsolat, az a gyanúm, hogy egy külön kapcsolótáblában tárolja, hogy melyik autóhoz mely kerekek tartoznak, és egy másikban a kerék csavar kapcsolatot.

HáDéSz előzmény
Szia köszi, hogy irtal!
elsőre logikailag van bukfenc a dologban: a Many oldalon akarod a kapcsolatot tárolni úgy, hogy a Many oldal nem tudhat arról, hogy kihez tartozik?
Igen így szeretnem!


Mivel egyirányú a kapcsolat, az a gyanúm, hogy egy külön kapcsolótáblában tárolja, hogy melyik autóhoz mely kerekek tartoznak, és egy másikban a kerék csavar kapcsolatot.

Igen belerakja a gyerek táblába az id-t előzmény
csak akkor tudja a Kerek táblában tárolni az autót, ha a kerék tudja, hogy melyik autóhoz tartozik, ha az ez irányú láthatóságot nem szeretnéd, akkor csak kapcsolótáblás megoldás lehet, hiszen nem tehetsz olyan mezőt a táblába, ami valamilyen módon ne látszana az entitásban.

Úgy ahogy szeretnéd, nem tudod megtenni, mivel az sértené az adatrejtés elvét(több adat lenne a táblában, mint amennyire az egyednek szüksége van). Ha mindenképpen a kerék táblában akarod tárolni, akkor mindkét irányban láthatóvá kell tenned a kapcsolatot.

Miért ennyire fontos, hogy egyirányú legyen?

HáDéSz előzmény
Eleinte így terveztük de mivel sok munka lenne átírni kétirányúra, ezért kerestünk egy megoldást így. De ha más ötlet nincs akkor átírjuk kétirányúra. előzmény
Ez sajnos nem ötlet kérdése, hanem szabvány, és abban így határozták meg... előzmény
csak egy tipp:

auto.getKerekList().add(kerek)
helyett:
List<Kerek> kerekList = new ArrayList<Kerek>();
kerekList.addAll(auto.getKerekList());
kerekList.add(kerek)
auto.setKerekList(kerekList)

Legalábbis úgy tudom hogy, ha nem változik maga a lista objektum, akkor nem perzisztál, hiába teszel bele új elemeket. Ahhoz hogy jól kezelje, egy másik listát kell átadni.
előzmény
Esetleg érdemes lehet az Auto persistálása után egy
em.flush();
hívást kiadni.

Ha DB generálja az ID-t az ugyanazon tranzakción belül nem mindig kerül be a managed entitásba.Épp ez miatt a legjobb talán az lenne ha az Autot a Kereket és a Csavart illetve a köztük lévő kapcsolatokat külön tranzakciókban hoznád létre.Valahogy így:


public void persist(){

Auto auto = this.persistAuto();
Kerek kerek = this.persistKerek();
auto.getKerekList().add(kerek);
auto = em.merge(auto);

}

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public Auto persistAuto(){

Auto auto = new Auto();
em.persist(auto);

return auto;

}

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public Kerek persistKerek(){

Kerek kerek = new Kerek();
em.persist(kerek);

return kerek;

}
előzmény
Oszd meg!