Co dokładnie oznacza strona będąca właścicielem ? Jakie jest wyjaśnienie z kilkoma przykładami mapowania ( jeden do wielu, jeden do jednego, wiele do jednego )?
Poniższy tekst jest fragmentem opisu @OneToOne w dokumentacji Java EE 6. Widać w tym koncepcję będącą właścicielem .
Definiuje jednowartościowe powiązanie z inną jednostką, która ma wielokrotność jeden do jednego. Zwykle nie jest konieczne jawne określanie skojarzonej jednostki docelowej, ponieważ zwykle można to wywnioskować z typu obiektu, do którego się odwołujemy. Jeśli relacja jest dwukierunkowa, strona niebędąca właścicielem musi użyć elementu mappedBy adnotacji OneToOne, aby określić pole relacji lub właściwość strony będącej właścicielem.
Odpowiedzi:
Dlaczego pojęcie strony będącej właścicielem jest konieczne:
Idea strony właścicielskiej relacji dwukierunkowej bierze się stąd, że w relacyjnych bazach danych nie ma relacji dwukierunkowych, jak w przypadku obiektów. W bazach danych mamy tylko relacje jednokierunkowe - klucze obce.
Jaki jest powód nazwy „strona właścicielska”?
Strona będąca właścicielem relacji śledzonej przez Hibernate to strona relacji, która jest właścicielem klucza obcego w bazie danych.
Jaki problem rozwiązuje pojęcie posiadania strony?
Weźmy przykład dwóch obiektów zmapowanych bez deklarowania strony będącej właścicielem:
Z punktu widzenia obiektu obiektowego to odwzorowanie definiuje nie jedną relację dwukierunkową, ale dwie oddzielne relacje jednokierunkowe.
Mapowanie spowodowałoby nie tylko tabele
PERSONS
iID_DOCUMENTS
, ale także utworzyć trzecią tabelę skojarzeńPERSONS_ID_DOCUMENTS
:Zwróć uwagę tylko
pk
na klucz podstawowyID_DOCUMENTS
. W tym przypadku Hibernate śledzi obie strony relacji niezależnie: jeśli dodasz dokument do relacjiPerson.idDocuments
, wstawi on rekord do tabeli asocjacjiPERSON_ID_DOCUMENTS
.Z drugiej strony, jeśli wywołasz
idDocument.setPerson(person)
, zmieniamy klucz obcy person_id w tabeliID_DOCUMENTS
. Hibernate tworzy w bazie danych dwie relacje jednokierunkowe (klucz obcy) w celu zaimplementowania jednej dwukierunkowej relacji z obiektem.Jak pojęcie strony właścicielskiej rozwiązuje problem:
Wiele razy to, czego chcemy, to tylko klucz obcy w tabeli w
ID_DOCUMENTS
kierunkuPERSONS
i dodatkowa tabela asocjacji.Aby rozwiązać ten problem, musimy tak skonfigurować Hibernację, aby przestała śledzić modyfikacje relacji
Person.idDocuments
. Hibernacja powinna śledzić tylko drugą stronę relacjiIdDocument.person
i w tym celu dodajemy mappedBy :Co to znaczy mappedBy?
Czy są jakieś GOTCHA, konsekwencje?
Korzystanie mappedBy , jeżeli tylko zadzwonić
person.getDocuments().add(document)
, klucz obcy wID_DOCUMENTS
będzie nie być związane z nowym dokumentem, ponieważ to nie jest będącym właścicielem / śledzone strona relacji!Aby połączyć dokument z nową osobą, musisz jawnie wywołać
document.setPerson(person)
, ponieważ jest to strona będąca właścicielem relacji.Podczas korzystania z mappedBy deweloper jest odpowiedzialny za poznanie strony będącej właścicielem i zaktualizowanie właściwej strony relacji w celu wyzwolenia trwałości nowej relacji w bazie danych.
źródło
person.getDocuments().add(document)
”, hibernacja aktualizuje klucz obcyID_DOCUMENTS
.@OneToMany
adnotacji, który można ustawić na UTRZYMAJ, w tym przypadku hibernacja zapisze wszystkie połączone jednostki w bazie danych. Czy ktoś może to wyjaśnić - dlaczego autor mówi, że hibernacja nie będzie śledzić zmian po stronie nie będącej właścicielem - ale w rzeczywistości hibernacja wykonuje śledzenie?Możesz sobie wyobrazić, że stroną będącą właścicielem jest byt, który ma odniesienie do drugiej. W swoim fragmencie masz relację jeden do jednego. Ponieważ jest to relacja symetryczna , w końcu uzyskasz to, że jeśli obiekt A jest w relacji z obiektem B, to również odwrotnie jest prawdą.
Oznacza to, że zapisanie w obiekcie A odniesienia do obiektu B i zapisanie w obiekcie B odniesienia do obiektu A będzie zbędne: dlatego wybierasz, który obiekt „jest właścicielem” drugiego, który ma do niego odniesienie.
Gdy masz relację jeden do wielu, obiekty związane z częścią „wiele” będą stroną będącą właścicielem, w przeciwnym razie będziesz musiał przechowywać wiele odniesień od pojedynczego obiektu do wielu. Aby tego uniknąć, każdy obiekt w drugiej klasie będzie miał wskaźnik do pojedynczego obiektu, do którego się odnosi (więc jest stroną będącą właścicielem).
W przypadku relacji wiele do wielu, ponieważ i tak będziesz potrzebować osobnej tabeli mapowania, nie będzie żadnej strony będącej właścicielem.
Podsumowując, strona będąca właścicielem jest podmiotem, który ma odniesienie do drugiej.
źródło
@ManyToMany
relacje również mają strony będące właścicielami. Podobnie,@OneToMany
relacje mogą używać tabel łączenia, ale nadal musisz określić stronę będącą właścicielem.