# ManyToOne Beziehung persistieren



## y0dA (19. Jul 2010)

Hallo!

Folgendes:
Ich habe eine xhtml Seite wo der User Daten zum persistieren eingeben kann, bspw: Name,Vorname etc und hierbei muss der User auch eine "Marke" eingeben und selbige entspricht einer anderen Tabelle.


```
public class Person {
@Id
// hier steht die Sequence
private Integer id;

 private String name;
...
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "marke")
private Marke marke;


public class Marke {

@Id
// hier steht die Sequence
private Integer id;

private String bezeichnung;



public T create(T entity) throws EntityExistsException,
			IllegalStateException, IllegalArgumentException,
			TransactionRequiredException {
		em.persist(entity);

		return entity;
	}
```

Nun ist es so dass wenn ich nun die Person speichern möchte, der User zuvor per Selectbox eine "Marke" gewählt hat und ich von selbiger dann die ID kenne. Wie geht man hier nun vor, lädt man vorm persistieren die Marke aus der DB? Oder gibt man dem Objekt Person einfach ein new Marke(id) mit (alle anderen Felder sind dann nicht befüllt)? Letzteres habe ich versucht und klappt auch, nur bekomme ich leider nachdem persistieren dass Marke Objekt nicht nachgeladen, sprich im Person Objekt ist dann noch immer das Marke Objekt mit ID und alle anderen Felder sind nicht befüllt.


----------



## y0dA (19. Jul 2010)

Also hat hier auch mal wieder niemand eine manytoone Beziehung persistiert und weiß deshalb nicht ob nachdem persistieren die Objekte nachgeladen werden bzw. ob das ginge.


----------



## maki (19. Jul 2010)

y0dA hat gesagt.:


> Also hat hier auch mal wieder niemand eine manytoone Beziehung persistiert und weiß deshalb nicht ob nachdem persistieren die Objekte nachgeladen werden bzw. ob das ginge.


Wow, 2 Stunden und 45 Minuten keine Antwort bekommen, und schon motzen...



> Nun ist es so dass wenn ich nun die Person speichern möchte, der User zuvor per Selectbox eine "Marke" gewählt hat und ich von selbiger dann die ID kenne. Wie geht man hier nun vor, lädt man vorm persistieren die Marke aus der DB?


Nun, das ganze heisst ja ORM weil es Objektgraphen persistiert, eine ID reicht natürlich nicht aus, muss schon das richtige Objekt sein.
Aber imho sollte das Marke Objekt an dieser Stelle (GUI Anzeige) schon längst geladen sein 



> Oder gibt man dem Objekt Person einfach ein new Marke(id) mit (alle anderen Felder sind dann nicht befüllt)? Letzteres habe ich versucht und klappt auch, nur bekomme ich leider nachdem persistieren dass Marke Objekt nicht nachgeladen, sprich im Person Objekt ist dann noch immer das Marke Objekt mit ID und alle anderen Felder sind nicht befüllt.


Genauso hätte ich das auch erwartet bei diesem Vorgehen


----------



## y0dA (19. Jul 2010)

Es sollte nicht als "motzen" aufgenommen werden, mich macht der OR Mapper nur, in den letzten Tagen, ziemlich fertig - habe bis dato nicht wirklich was damit gemacht. Weiters habe ich auf meine letzten Threads leider auch keine Antwort bekommen und deshalb war ich halt schon ein wenig gefrustet - und dies war halt schon mal anders.

Also ich kann eigentlich schon auch nur mit der ID persistieren, sprich die Beziehung ist dann auch korrekt in der DB abgelegt nur das Result des Statements beinhaltet halt nicht das komplette Objekt sondern nur die ID (selbiges Objekt war zuvor aber schon in der DB persistent - wie ich schon geschrieben habe habe ich die ID von einer Selectbox und das restliche Objekt ist nicht mehr in der Session etc --> wir müssen hier mit wenig Speicher auskommen und somit kann ich das Objekt nicht "spazieren tragen"). Oder soll ich etwa das Objekt, wo ich nur die ID kenne, aus der DB laden und im Anschluss selbiges in Objekt B zum speichern setzen?


----------



## SlaterB (19. Jul 2010)

> Oder soll ich etwa das Objekt, wo ich nur die ID kenne, aus der DB laden und im Anschluss selbiges in Objekt B zum speichern setzen? 

das bietet sich schon an, allein um zu testen, ob die ID gültig ist,
so ein Speichern ist an sich ein aufwendiger und hoffentlich nicht allzu häufiger Vorgang, 
da braucht man im Allgemeinen nicht übermäßig performant sein

im Allgemeinen ist die Idee 'nur Id zuordnen, fertig' aber auch interessant, sollte technisch machbar sein,
entweder unterstützt Hibernate das irgendwie oder nicht,
Hibernate selber lädt ja schon Proxies, die erst später initialisiert werden, es müsste 
Session.createProxy(class,Id) 
geben

ich habe da soeben 5 Min. nach geschaut, aber nix gefunden und ist mir auch nicht bekannt, falls diese Einzelmeinung weiterhilft


----------



## maki (19. Jul 2010)

> Es sollte nicht als "motzen" aufgenommen werden, mich macht der OR Mapper nur, in den letzten Tagen, ziemlich fertig - habe bis dato nicht wirklich was damit gemacht. Weiters habe ich auf meine letzten Threads leider auch keine Antwort bekommen und deshalb war ich halt schon ein wenig gefrustet - und dies war halt schon mal anders.


Schon ok 



> Also ich kann eigentlich schon auch nur mit der ID persistieren, sprich die Beziehung ist dann auch korrekt in der DB abgelegt nur das Result des Statements beinhaltet halt nicht das komplette Objekt sondern nur die ID (selbiges Objekt war zuvor aber schon in der DB persistent - wie ich schon geschrieben habe habe ich die ID von einer Selectbox und das restliche Objekt ist nicht mehr in der Session etc --> wir müssen hier mit wenig Speicher auskommen und somit kann ich das Objekt nicht "spazieren tragen")


Nein & Nein

Eine ID reicht eben nicht, wie oben gesagt, du brauchst schon das Objekt.



> Oder soll ich etwa das Objekt, wo ich nur die ID kenne, aus der DB laden und im Anschluss selbiges in Objekt B zum speichern setzen?


Du dennst immer noch nicht ORM genug.
Du denkst immer noch IDs & Primärschlüssel.
Eine ID reicht nicht, das Obejkt sollte doch schon auch vorher geladen sein, oder wie befüllst du die SelectBox???

Tipp: Lese dich noch mehr in JPA/ORM ein, sonst wird das ncoh viel frustrierender.
Die JPA 1.0 Spek. empfand ich sehr angenehm zum Lesen & Lernen, k.A. wie das bei JPA 2.0 ist.

Zu deinem anderen Thread kann ich nix sagen, weil ich OpenJPA nicht kenne.

Ps: Nur IDs einzutragen wird übrigens Probleme machen, wie sehen denn deine Equals & Hashcode Methoden aus?


----------



## SlaterB (19. Jul 2010)

maki hat gesagt.:


> Eine ID reicht nicht, das Obejkt sollte doch schon auch vorher geladen sein, oder wie befüllst du die SelectBox???


im Webumfeld ist das eine alte Anfrage, völlig losgelöst, vielleicht gar ein Bookmark von letzter Woche/ lokal abgespeichert,

selbst bei einer Swing-GUI kann man zwischen getrennter DB- und Anzeigeschicht DTO übertragen,
ist doch völlig normal?


----------



## maki (19. Jul 2010)

SlaterB hat gesagt.:


> im Webumfeld ist das eine alte Anfrage, völlig losgelöst, vielleicht gar ein Bookmark von letzter Woche/ lokal abgespeichert,
> 
> selbst bei einer Swing-GUI kann man zwischen getrennter DB- und Anzeigeschicht DTO übertragen,
> ist doch völlig normal?


DTOs sind gut 
Diese müssen dann aber hin- und wieder zurück "transformiert" werden, dazu gibt es zB. den TransferObjektAssembler, aber etwas mehr als eine ID muss schon dabei sein.

Dein Beispiel mit der ID in der URL ist eher etwas für REST, da muss vorher natürlich erst ein Lookup stattfinden.

Mit JSF ist geht das übrigens auch ohne DTOs, da gibt es Converter die das Übernehmen, soll heissen: Ich befülle eine SelectBox mit einer Entity, nicht mit Strings, zurückbekomme ich auch eine Entity, nicht Strings, das übernimmt der Converter. Im Falle von DTOs ist es natürlich keine Entity, sondern ein DTO 

Nebenbei, wenn das Objekt schon geladen wurde in der Session, muss es nciht nochmals geladen werden aus der DB, sondern es kommt aus einer sog. P of EAA: Identity Map


----------



## y0dA (19. Jul 2010)

Vorweg gehts hier doch gar nicht um Hibernate, ich habe openJPA nicht erwähnt weil sich sonst wieder keiner meldet  - meine Fragen zielen ja auch viel mehr auf allgm. JPA ab als auf spezifische Dinge.
Fakt ist dass ich beim persistieren vom Objekt B wo ich nur die ID kenne ein neues Objekt desselben erzeugt und *nur* die ID gesetzt und dieses Objekt B dann wieder in Objekt A gesetzt und Objekt A genauso gespeichert --> Resultat, beide Tabellen befüllt; leider Daten von Objekt B nicht automatisch nachgeladen.

Wenn ich die Selectitems erzeuge dann ist von jener Tabelle die ID das value und die Bezeichnung das Label, den Rest von dem Objekt merke ich mir nicht und somit müsste ich das Objekt nun nochmal laden oder eben schon vor dem persistieren laden.

Wie sieht euer best practise hierbei aus?
Handelt ihr mit den Selectboxen anders?

**EDIT**


maki hat gesagt.:


> DTOs sind gut
> Diese müssen dann aber hin- und wieder zurück "transformiert" werden, dazu gibt es zB. den TransferObjektAssembler, aber etwas mehr als eine ID muss schon dabei sein.
> 
> Dein Beispiel mit der ID in der URL ist eher etwas für REST, da muss vorher natürlich erst ein Lookup stattfinden.
> ...



Also wenn das Objekt schon einmal geladen wurde dann gehe ich auch nicht mehr auf die DB? Gilt das innerhalb einer Transaktion oder der gesamten Session?

Also könnte ich eigentlich auch in meine Selectbox das ganze Objekt reinlegen - diese Converter muss ich mir mal ansehen.
Eher die Selectbox mit dem ganzen Objekt oder lieber das Objekt "nachladen"?


----------



## maki (19. Jul 2010)

> Fakt ist dass ich beim persistieren vom Objekt B wo ich nur die ID kenne ein neues Objekt desselben erzeugt und nur die ID gesetzt und dieses Objekt B dann wieder in Objekt A gesetzt und Objekt A genauso gespeichert --> Resultat, beide Tabellen befüllt; leider Daten von Objekt B nicht automatisch nachgeladen.
> 
> Wenn ich die Selectitems erzeuge dann ist von jener Tabelle die ID das value und die Bezeichnung das Label, den Rest von dem Objekt merke ich mir nicht und somit müsste ich das Objekt nun nochmal laden oder eben schon vor dem persistieren laden.


Das ist dein Problem, wie gesagt, du denkst noch IDs bzw. Primärschlüssel, bei ORM geht es um Objektgraphen, IDs sind technische Details die man meist ignorieren sollte (auch in der Equals & Hashcode Methode, sonst gibt es Probleme ).



> Also könnte ich eigentlich auch in meine Selectbox das ganze Objekt reinlegen - diese Converter muss ich mir mal ansehen.


Ja, wobei, ich kenne mich ehrlich gesagt mit Swing überhaupt nicht aus 
JSF soll aber ziemlich stark daran angelehnt sein, gibt es in Swing keine Converter?
Kann mir nicht vorstellen dass in Swing alles wieder auf Strings runtergebrochen würde, wäre ja schlechter umgesetzt als im Web mit JSF...


----------



## maki (19. Jul 2010)

> Kannst du meinen Thread in das "richtige" Unterforum verschieben?


Teile davon, denn den JPA Teil sollten wir hier lassen 

Bitte schön: http://www.java-forum.org/web-tier/103451-jsf-entites-selectitems-converter.html


----------

