2012-06-10 14 views
5

co dokładnie jest różnica w dwóch następujących deklaracjiJPA - różnica w korzystaniu z nieruchomości mappedBy zdefiniowanie podmiotu posiadania

B jest stroną będącym właścicielem

@Entity 
class A { 
    @Id int id; 

    @OneToOne 
    B b; 
} 

@Entity 
class B { 
    @Id int id; 

    @OneToOne(mappedBy="b") 
    A a; 
} 

A jest strona będącym właścicielem

@Entity 
class A { 
    @Id int id; 

    @OneToOne(mappedBy="a") 
    B b; 
} 

@Entity 
class B { 
    @Id int id; 

    @OneToOne 
    A a; 
} 

myślenie o tym w „normalnym SQL” myślę, że jest taka sama jak posiadanie dwóch tabel każdy mający klucz obcy w innej tabeli. Nie rozumiem jednak, jaki jest wpływ określenia, która jednostka jest po stronie posiadania, tj. Za pomocą właściwości "mappedBy". Co to właściwie oznacza, ponieważ nie wierzę, że istnieje odpowiednik w normalnym SQL.

+2

Czy sprawdziłeś, czy w obu przypadkach tabele A i B będą miały ze sobą FK? –

Odpowiedz

10

JPA 2.0 specification, sekcja 2.9, pisze:

Relacje mogą być dwukierunkowe lub jednokierunkowe. Relacja dwukierunkowa ma zarówno stronę będącą właścicielem, jak i stronę odwrotną (nie będącą właścicielem). Związek jednokierunkowy ma tylko stronę posiadania. Własna strona relacji określa aktualizacje relacji w bazie danych, zgodnie z opisem w sekcji 3.2.4.

obowiązują następujące zasady do relacji dwukierunkowych:

  • Odwrotna strona relacji dwukierunkowego musi odnosić się do jego posiadanie strony z wykorzystaniem elementu mappedBy z OneToOne, OneToMany lub ManyToMany adnotacji. Element mappedBy oznacza właściwość lub pole w encji, która jest właścicielem relacji.
  • Wiele stron relacji dwukierunkowych jeden-do-wielu/wiele-do-jednego musi być po stronie posiadania, dlatego elementu mappedBy nie można określić w adnotacji ManyToOne.
  • Dla relacji dwukierunkowych jeden-do-jednego strona własna odpowiada stronie zawierającej odpowiedni klucz obcy.
  • Dla wielu dwukierunkowych relacji każda ze stron może być stroną posiadacza.

Odpowiednie części sekcji 3.2.4 są:

Stan podmiotów utrzymujących są synchronizowane z bazą danych przy zatwierdzaniu transakcji. Ta synchronizacja obejmuje zapisywanie do bazy danych wszelkich aktualizacji trwałych elementów i ich relacji, jak określono powyżej.

i

dwukierunkowe relacje pomiędzy podmiotami zarządzanych będą utrzymywały się na podstawie referencji posiadanych przez strony posiadania relacji. Deweloperzy są odpowiedzialni za utrzymywanie w pamięci odniesień przechowywanych po stronie własnej i tych przechowywanych po stronie odwrotnej, zgodnych ze sobą, kiedy się zmieniają. W przypadku jednokierunkowych relacji jeden-do-jednego i jeden-do-wielu, obowiązkiem programisty jest upewnienie się, że semantyka relacji jest przestrzegana.

Szczególnie ważne jest, aby upewnić się, że zmiany w odwrotnej strony w wyniku relacji w odpowiednich aktualizacji na stronie posiadania, tak aby zapewnić, że zmiany nie zostaną utracone, gdy są one synchronizowane z bazą danych.

+1

+1 dla odniesień do specyfikacji. –

+0

Myślę, że to kończy wszystkie inne odpowiedzi :-) +1 – siebz0r

4

W pierwszym przykładzie tabela A będzie miał 2 kolumny id i b_id tabela B będzie mieć jedną kolumnę, id. To sprawia, że ​​A jest właścicielem.

W drugim przykładzie B jest stroną będącą właścicielem. B ma dwie kolumny: id i a_id. A będzie mieć jedną kolumnę, id.

I to jest różnica :-)

3

Bok będącym właścicielem jest strona, która uważa, JPA wiedzieć to stowarzyszenie istnieje, czy nie. Załóżmy, że idziesz z pierwszym przykładem. Strona posiadająca to strona, w której nie ma atrybutu mappedBy. Bok będącym właścicielem jest zatem, a nie B.

Oznacza to, że jeśli masz A i B w bazie danych, a ty

A a = em.find(A.class, aId); 
B b = em.find(B.class, bId); 
a.setB(b); 

JPA uratuje stowarzyszenie (czyli będzie przechowywać Identyfikator B w kolumnie łączenia tabeli A).

Ale jeśli nie

A a = em.find(A.class, aId); 
B b = em.find(B.class, bId); 
b.setA(a); 

nic nie zostanie zmienione w bazie danych, ponieważ zmodyfikowany odwrotną stronę i zapomniał modyfikować strony posiadania.

6

Jako drugi podkreśliło, mylisz się, po której stronie jest boczny będącego właścicielem firmy przykładach. "Posiadanie strony" oznacza posiadanie relacji z perspektywy OO, w praktyce, która często kończy się jako przeciwieństwo tego, jak jest lub będzie generowana w db, jeśli używa się rdbm jako dostawcy trwałości.

W normalnych okolicznościach model OO wyraźnie określa, które strony są po stronie użytkownika. Na przykład zamówienie ma linie zamówienia. W przypadku usunięcia zamówienia wszystkie zamówienia należy usunąć. Jeśli usuniemy Linię Zakonną, Zakon prawdopodobnie nadal ma prawo do istnienia. Stąd Zakon jest stroną posiadacza.

Aby uzyskać bardziej konkretny i doskonały przykład, na temat skutków, jakie strona ma po swojej stronie, odnoszę się do odpowiedzi @JB Nizet.

Zgodnie z sekcją 2.9 w JPA 2.0 spec:

Na jeden do jednego relacji dwukierunkowych, będącym właścicielem strona odpowiada stronie zawierającej odpowiedni klucz obcy.

Ale w tym samym rozdziale również:

Ponadto, w tym opisie również wymaga wsparcia dla następujących alternatywnych strategii mapowania [..] Mapowanie jednokierunkowym i dwukierunkowym jedno- relacje jeden do jednego, dwukierunkowe relacje wiele do jednego/jeden do wielu i jednokierunkowe relacje wiele-do-jednego za pomocą mapowania złączeń odwzorowania.

Nieco dodatkowych wojsk w tej samej sekcji, że kontynuuje się:

Dodatkowe adnotacje odwzorowania (np kolumny i tabela odwzorowania adnotacje) można które określił zastąpić lub dalej udoskonalić domyślne mapowania i strategie mapowania opisane w rozdziale 2.10. Niektóre implementacje wykorzystują to, aby umożliwić FK dwukierunkowego OneToOne w tabeli docelowej.

Aby odczytać niektóre o niektórych strategiach rozwiązać ten scenariusz, patrz: An almost good explaination

Nie sprawdzałem ale mam nadzieję i wierzę, że 2,1 usunie pierwszy cytat. Ponieważ faktyczna struktura bazy danych powinna w jak najmniejszym stopniu ograniczać sposób, w jaki możemy modelować dane jako jednostki.

+0

Nie, JPA określa, że ​​właścicielem strony skojarzenia dwukierunkowego OneToOne jest ten, który zawiera klucz obcy. To samo dotyczy dwukierunkowego OneToMany. –

+0

"i może być użyty w odwzorowaniu OneToOne, w którym klucz podstawowy encji odwołującej jest używany jako klucz obcy dla przywoływanej jednostki." http://docs.oracle.com/javaee/6/api/javax/persistence/PrimaryKeyJoinColumn.html. Sytuacja _just_ nie pojawia się tak często. – esej

+0

I to niczego nie zmienia. W tym przypadku kolumną klucza podstawowego jest kolumna łączenia (stąd nazwa PrimaryKeyJoinColumn), a podmiot zawierający tę adnotację, a tym samym kolumna sprzężenia, jest stroną będącą właścicielem. Przeczytaj odpowiedź @ meriton, zawierającą ten fragment ze specyfikacji JPA: "Dla relacji dwukierunkowych jeden do jednego strona własna odpowiada stronie zawierającej odpowiedni klucz obcy". –

Powiązane problemy