Jaka jest różnica między jednokierunkowym i dwukierunkowym JPA a asocjacjami Hibernate?

Jaka jest różnica między asocjacjami jednokierunkowymi i dwukierunkowymi?

Ponieważ tabela wygenerowana w db są takie same,więc jedyną różnicą, jaką znalazłem, jest to, że każda strona asokacji dwukierunkowej będzie miała odniesienie do drugiej, a jednokierunkowa nie.

Jest to związek jednokierunkowy

public class User {
    private int     id;
    private String  name;
    @ManyToOne
    @JoinColumn(
            name = "groupId")
    private Group   group;
}

public class Group {
    private int     id;
    private String  name;
}

Stowarzyszenie dwukierunkowe

public class User {
    private int     id;
    private String  name;
    @ManyToOne
    @JoinColumn(
            name = "groupId")
    private Group   group;
}
public class Group {
    private int         id;
    private String      name;
    @OneToMany(mappedBy="group")
    private List<User>  users;
}

Różnica polega na tym, czy grupa posiada odniesienie użytkownika.

Więc zastanawiam się, czy to jedyna różnica? co jest zalecane?
Author: Vlad Mihalcea, 2011-03-19

4 answers

Główną różnicą jest to, że relacja dwukierunkowa zapewnia dostęp nawigacyjny w obu kierunkach, dzięki czemu można uzyskać dostęp do drugiej strony bez wyraźnych zapytań. Umożliwia również zastosowanie opcji kaskadowych w obu kierunkach.

Zauważ, że dostęp nawigacyjny nie zawsze jest dobry, szczególnie w przypadku relacji "jeden-do-bardzo-wielu" i "wiele-do-bardzo-wielu". Wyobraź sobie Group, który zawiera tysiące Users:

  • Jak byś się do nich dostał? Z tak wieloma User s, Zwykle musisz zastosować filtrowanie i / lub stronicowanie, aby i tak wykonać zapytanie (chyba że używasz filtrowania kolekcji , co dla mnie wygląda jak hack). Niektórzy programiści mogą mieć tendencję do filtrowania w pamięci w takich przypadkach, co oczywiście nie jest dobre dla wydajności. Zauważ, że posiadanie takiej relacji może zachęcić tego rodzaju programistów do korzystania z niej bez uwzględniania implikacji wydajności.
  • Jak dodać nowe User s do Group? Na szczęście Hibernate przygląda się własnościowej stronie Związku, gdy go utrzymuje, więc można ustawić tylko User.group. Jeśli jednak chcesz zachować spójność obiektów w pamięci, musisz również dodać User do Group.users. Ale to sprawi, że Hibernate pobierze wszystkie elementy Group.users z bazy danych!

Więc nie mogę się zgodzić z zaleceniem z najlepszych praktyk. Musisz starannie zaprojektować dwukierunkowe relacje, biorąc pod uwagę przypadki użycia (czy potrzebujesz dostęp nawigacyjny w obu kierunkach?) i ewentualne implikacje wydajnościowe.

Zobacz też:

 162
Author: axtavt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-10 03:32:54

Istnieją dwie główne różnice.

Dostęp do stron Stowarzyszenia

Pierwszy jest związany z tym, jak uzyskasz dostęp do Związku. W przypadku asocjacji jednokierunkowej można poruszać się po asocjacji tylko z jednego końca.

Więc dla jednokierunkowego związku @ManyToOne oznacza to, że możesz uzyskać dostęp do Związku tylko od strony dziecka, gdzie znajduje się klucz obcy.

Jeśli masz jednokierunkową asocjację @OneToMany, oznacza to, że możesz uzyskać dostęp tylko do relacja ze strony rodzica, który zarządza kluczem obcym.

W przypadku dwukierunkowego asocjacji @OneToMany można poruszać się w obu kierunkach, zarówno od strony rodzica, jak i od strony dziecka.

Musisz również użyć metod Dodaj/usuń dla dwukierunkowych skojarzeń, aby upewnić się, że obie strony są prawidłowo zsynchronizowane.

Wydajność

[[8]}drugi aspekt jest związany z wydajnością.
  1. Dla @OneToMany, jednokierunkowe Asocjacje nie działają tak dobrze jak dwukierunkowe .
  2. dla @OneToOne, powiązanie dwukierunkowe spowoduje, że rodzic zostanie pobrany z niecierpliwością, jeśli Hibernate nie będzie w stanie określić, czy serwer Proxy powinien być przypisany, czy też wartość null.
  3. dla @ManyToMany, typ kolekcji ma spore znaczenie, ponieważ Sets działa lepiej niż Lists.
 36
Author: Vlad Mihalcea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-13 17:02:13

Jeśli chodzi o kodowanie, relacja dwukierunkowa jest bardziej złożona do wdrożenia, ponieważ aplikacja jest odpowiedzialna za utrzymywanie obu stron w synchronizacji zgodnie ze specyfikacją JPA 5 (na stronie 42). Niestety przykład podany w specyfikacji nie podaje więcej szczegółów, więc nie daje wyobrażenia o poziomie złożoności.

Gdy nie używasz bufora drugiego poziomu, zwykle nie jest problemem, aby nie mieć poprawnie zaimplementowanych metod relacji, ponieważ instancje zostanie odrzucony po zakończeniu transakcji.

Podczas korzystania z pamięci podręcznej drugiego poziomu, jeśli coś zostanie uszkodzone z powodu nieprawidłowo zaimplementowanych metod obsługi relacji, oznacza to, że inne transakcje będą również widzieć uszkodzone elementy (pamięć podręczna drugiego poziomu jest globalna).

Poprawnie zaimplementowana relacja dwukierunkowa może uprościć zapytania i Kod, ale nie powinna być używana, jeśli nie ma to sensu w logice biznesowej.

 11
Author: Constantino Cronemberger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-26 19:54:50

Nie jestem w 100% pewien, że to jest tylko różnica, ale to jest Główna Różnica. Zalecane jest również, aby mieć dwukierunkowe skojarzenia przez dokumenty Hibernate:

Http://docs.jboss.org/hibernate/core/3.3/reference/en/html/best-practices.html

Konkretnie:

Preferuj skojarzenia dwukierunkowe: Powiązania jednokierunkowe są trudniejsze do sprawdzenia. W dużym aplikacji, prawie wszystkie stowarzyszenia musi być żeglowna w obu kierunkach w zapytaniach.

Osobiście mam mały problem z tą rekomendacją-wydaje mi się, że są przypadki, w których dziecko nie ma żadnego praktycznego powodu, aby wiedzieć o swoim rodzicu (np. dlaczego element zamówienia musi wiedzieć o zamówieniu, z którym jest związany?), ale widzę w nim wartość w rozsądnej części czasu, jak również. A ponieważ dwukierunkowość tak naprawdę niczego nie boli, nie uważam jej za zbyt niestosowną do trzymaj się.

 9
Author: kvista,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-19 08:03:23