2013-04-20 31 views
25

Obecnie czytam dokumentację Hibernate dotyczącą entity associations i przychodzę napotkać trochę trudności, aby dowiedzieć się kilku rzeczy. Ma to zasadniczo związek z różnicami między skojarzeniami ManyToOne i OneToMany. Chociaż użyłem ich w prawdziwych projektach, nie mogę całkowicie zrozumieć różnic między nimi. Według mojej wiedzy, jeśli tabela/jednostka ma powiązanie ManyToOne z innym, powiązanie powinno być z drugiej strony OneToMany. Jak zatem zdecydować, który z nich wybrać na podstawie konkretnego przypadku i jak wpływa on na bazę danych/zapytania/wyniki? Czy wszędzie jest dobry przykład?Hibernate/JPA ManyToOne vs OneToMany

P.S .: Sądzę, że byłoby to pomocne ze względu na jego znaczenie dla pytania, gdyby ktoś mógł poza tym wyjaśnić, co jest istotą właściciela stowarzyszenia i różnicą między dwukierunkowym a jednokierunkowym powiązaniem.

Odpowiedz

43

Załóżmy, że masz zamówienie i zamówienie. Możesz zdecydować się na jednokierunkową OneToMany pomiędzy Kolejność i Linia zamówienia (Zamówienie będzie mieć kolekcję Linii zamówienia). Możesz też wybrać powiązanie ManyToOne między linią zamówienia i zamówieniem (OrderLine będzie mieć odniesienie do jego zamówienia). Możesz też wybrać oba, w którym to przypadku skojarzenie staje się dwukierunkowym skojarzeniem OneToMany/ManyToOne.

Wybrane rozwiązanie zależy głównie od sytuacji i poziomu powiązań między podmiotami. Na przykład, jeśli użytkownik, firma lub dostawca mają wiele adresów, sensownym byłoby posiadanie jednokierunkowego połączenia między każdym z nich a adresem, a adres nie będzie wiedział o ich właścicielu.

Załóżmy, że masz użytkownika i wiadomość, w której użytkownik może mieć tysiące wiadomości, to może mieć sens modelowanie go tylko jako ManyToOne z wiadomości dla użytkownika, ponieważ rzadko będziesz prosić o wszystkie wiadomości i tak użytkownik. Powiązanie może być dwukierunkowe tylko po to, aby pomóc w wyszukiwaniu zapytań, ponieważ kwerendy JPQL łączą się między elementami, przeglądając ich powiązania.

W powiązaniu dwukierunkowym można znajdować się w sytuacji, w której wykres obiektów jest niespójny. Na przykład, Zamówienie A miałoby pusty zestaw Linii Rozkazów, ale niektóre Linie Zamówień miałyby odniesienie do Zamówienia A. JPA narzuca, że ​​zawsze jedna strona asocjacji jest stroną właściciela, a druga strona jest stroną odwrotną. Odwrotna strona jest ignorowana przez JPA. Strona właściciela jest stroną, która decyduje, jaka relacja istnieje. W dwukierunkowym asocjacji OneToMany strona właściciela musi być po drugiej stronie. Tak więc w poprzednim przykładzie stroną właściciela byłaby OrderLine, a JPA zachowałoby powiązanie między wierszami a rzędem A, ponieważ linie mają odniesienie do A.

Takie skojarzenie będzie odwzorowane w następujący sposób:

kolejno:

@OneToMany(mappedBy = "parentOrder") // mappedBy indicates that this side is the 
    // inverse side, and that the mapping is defined by the attribute parentOrder 
    // at the other side of the association. 
private Set<OrderLine> lines; 

w ORDERLINE:

@ManyToOne 
private Order parentOrder; 
1

Ponadto, mając @ManytoOne stronie, co wymaga tylko właściciel n + q 1 podczas zapisywania asocjacji. Gdzie n jest liczbą skojarzeń (wiele stron).

mając na uwadze, że posiadanie @OneToMany jako właściciela, podczas wstawiania jednostki nadrzędnej (jednej strony) ze skojarzeniami (wiele stron) dałoby 2 * N + 1 zapytania. W którym jedno zapytanie dotyczy wstawienia asocjacji, a inne zapytanie dotyczyłoby aktualizacji klucza obcego w powiązanej jednostce.