# JPA oneToMany/ManyToOne bidirektional verwirrung



## continue (18. Mrz 2012)

Hallo,

habe ein paar fragen bezüglich beziehung zwischen den entities:

*Order * hat beispielsweise eine liste mit *Item * Objekten (mit der oneToMany Annotation) und *Item* hat zusätzlich einen Feld von *Order* (mit einer ManyToOne Annotaion). Dann sprich ich von einer bidirektionalen oneToMany beziehung richtig? Wäre die beziehung unidirektional würde würde das *Order* Field im *Item*-Entity fehlen. auch richtig?

Was ist hier der genaue unterschied zu einer bidirektionalen *ManyToOne *beziehung ?

Zum persistieren:
Wenn ich wieder eine solche bidirektionale beziehung habe,
ich cascade=CascadeType.PERSIST oder ALL eingestellt habe, muss ich dann die verweise trotzdem beiderseitig angeben? also auf der orderseite die methode addItem() aufrufen UND auf der Item Seite setOrder() oder reicht es wenn ich nur addItem() auf der order Seite aufrufe? 
In vielen Fällen werden nämlich beide seiten aufgerufen, was bei einem komplizierterem dbschema dann irgendwie einfach chaotisch wird.....

hoffe ich konnte mich klar ausdrücken 

liebe grüße


----------



## JanHH (19. Mrz 2012)

Nein, das Order-Field hättest Du auch bei einer unidirektionalen beziehung (IRGENDWO muss das schliesslich gespeichert werden), vorausgesetzt Du arbeitest da mit @JoinColumn.

Die Beziehung wird dadurch Bidirektional, dass sich das "mappedBy" bei der @OneToMany und das @JoinColumn bei der ManyToOne auf das SELBE Feld beziehen.

Die Antwort auf die zweite Frage weiss ich nicht auswendig aber das kannst Du doch an sich auch ganz leicht selbst ausprobieren..


----------



## continue (19. Mrz 2012)

bei meinem db-schema wird aber trotzdem nur auf EINER seite ein fremdschlüssel gespeichert...
umgesetzt auf das Order-Item Beispiel:

Nur in der Item Tabelle gibt es eine spalte "order id".
In der Order Tabelle werden keine schlüssel von item gespeichert.

Wieso spricht man dann trotzdem von einer BIDIREKTIONALEN Verbindung? 


```
@Entity
class Order {
...
...
private Collection<Item> items = new ArrayList<Item>();

...

@OneToMany(mappedBy="order")
public Collection<Item> getItems() {
   return items;
}
...
...
}
```


```
@Entity
class Item {
...
...
private Order order;

...
@ManyToOne
public Order getOrder() {
   return order;
...
...
}
}
```


----------



## nillehammer (19. Mrz 2012)

"Bidirektional" bezieht sich auf die Richtung der Navigierbarkeit einer Beziehung. In der Objektwelt braucht es dafür eine Referenzvariable auf beiden Seiten der Beziehung. In der Datenbankwelt sind Beziehungen implizit immer bidirektional. Es braucht den Fremdschlüssel nur auf einer Seite. Von dieser Seite aus ist die Beziehung direkt navigierbar. Von der anderen Seite aus braucht es eine entsprechende JOIN-Query.

Dazu das Beispiel Mitarbeiter, Abteilung:
Tabelle Mitarbeiter: id, name, fk_Abt
Tabelle Abteilung: id, name

Hier ist die Beziehung von Mitarbeiter zu Abteilung direkt über den Fremdschlüssel navigierbar. Ein Mitarbeiter "kennt" seine Abteilung. Die Abteilung "kennt" ihre Mitarbeiter zunächst nicht, aber mit folgender Query kann man alle Mitarbeiter einer Abteilung ermitteln:

```
SELECT a.id, a.name, m.name
FROM Abteilung a INNER JOIN Mitarbeiter m
ON a.id = m.fk_Abt
ORDER BY a.name, m.name
```


----------



## continue (19. Mrz 2012)

d.h. es gibt in der relationalen DB welt eigentlich gar keine unterscheidung zwischen uni/bi-direktional?


----------



## nillehammer (19. Mrz 2012)

Ich kenne die Bezeichnungen Uni-/Bidirektional nur aus der Objektorientierten Welt. Aus der Relationalen Welt kenne ich das nicht. Es gibt zwar in ER-Diagrammen auch Pfeile, die drücken aber nicht die Navigationsrichtung aus, sondern das REFERENCES eines Fremdschlüssels.


----------



## JanHH (20. Mrz 2012)

Naja, die "Bidirektionalität" bezieht sich halt darauf, ob man per JPA von einem Objekt jeweils auf das andere zugreifen kann (also, wie schon geschrieben, die Navigierbarkeit). Das andere ist ja eher ein theoretisches Konzept. Die Items-Tabelle hat eine Order-Spalte, und wir wissen was damit gemeint ist und wie die beiden in Verbindung zueinander stehen. Aber das muss man JPA ja auch entsprechend klar machen.

Order A enthält Item B, entsprechend gehört Item B zu Order A. JPA weiss das, da sich beide Annotationen auf dieselbe Fremdschlüssel-Spalte beziehen.

Es wäre ja auch denkbar, dass Order A Item B enthält, aber von Sicht von Item B aus Item B "denkt", es würde zu Order C gehören. Das wäre dann natürlich ein Fehler, aber von der Struktur her die Konsequenz, wenn bei beiden Kardinalitäten nicht dieselbe Fremdschlüssel-Spalte angegeben werden würde.


----------

