Warum ist die Vorstellung einer Besitzerseite notwendig:
Die Idee einer Besitzerseite einer bidirektionalen Beziehung beruht auf der Tatsache, dass es in relationalen Datenbanken keine bidirektionalen Beziehungen wie bei Objekten gibt. In Datenbanken haben wir nur unidirektionale Beziehungen - Fremdschlüssel.
Was ist der Grund für den Namen "Besitzerseite"?
Die Besitzerseite der von Hibernate verfolgten Beziehung ist die Seite der Beziehung, die den Fremdschlüssel in der Datenbank besitzt.
Was ist das Problem, das der Begriff des Besitzes einer Seite löst?
Nehmen Sie ein Beispiel für zwei zugeordnete Entitäten, ohne eine Besitzerseite zu deklarieren:
@Entity
@Table(name="PERSONS")
public class Person {
@OneToMany
private List<IdDocument> idDocuments;
}
@Entity
@Table(name="ID_DOCUMENTS")
public class IdDocument {
@ManyToOne
private Person person;
}
Aus OO-Sicht definiert diese Abbildung nicht eine bidirektionale Beziehung, sondern zwei separate unidirektionale Beziehungen.
Die Zuordnung schaffen würde nicht nur Tabellen PERSONS
und ID_DOCUMENTS
, sondern auch eine dritte Zuordnungstabelle erstellen PERSONS_ID_DOCUMENTS
:
CREATE TABLE PERSONS_ID_DOCUMENTS
(
persons_id bigint NOT NULL,
id_documents_id bigint NOT NULL,
CONSTRAINT fk_persons FOREIGN KEY (persons_id) REFERENCES persons (id),
CONSTRAINT fk_docs FOREIGN KEY (id_documents_id) REFERENCES id_documents (id),
CONSTRAINT pk UNIQUE (id_documents_id)
)
Beachten Sie die Primärschlüssel pk
auf ID_DOCUMENTS
nur. In diesem Fall verfolgt der Ruhezustand beide Seiten der Beziehung unabhängig voneinander: Wenn Sie der Beziehung ein Dokument hinzufügen Person.idDocuments
, wird ein Datensatz in die Zuordnungstabelle eingefügt PERSON_ID_DOCUMENTS
.
Wenn wir dagegen aufrufen idDocument.setPerson(person)
, ändern wir den Fremdschlüssel person_id in der Tabelle ID_DOCUMENTS
. Hibernate erstellt zwei unidirektionale (Fremdschlüssel-) Beziehungen in der Datenbank, um eine bidirektionale Objektbeziehung zu implementieren .
Wie der Gedanke, eine Seite zu besitzen, das Problem löst:
Viele Male , was wir wollen , ist nur ein Fremdschlüssel auf dem Tisch ID_DOCUMENTS
hin PERSONS
und die zusätzliche Zuordnungstabelle.
Um dies zu lösen, müssen wir den Ruhezustand so konfigurieren, dass die Änderungen an der Beziehung nicht mehr verfolgt werden Person.idDocuments
. Der Ruhezustand sollte nur die andere Seite der Beziehung verfolgen. DazuIdDocument.person
fügen wir mappedBy hinzu :
@OneToMany(mappedBy="person")
private List<IdDocument> idDocuments;
Was bedeutet mappedBy?
Dies bedeutet
ungefähr : "Änderungen auf dieser Seite der Beziehung werden bereits von der anderen Seite der Beziehung IdDocument.person zugeordnet, sodass Sie sie hier nicht separat in einer zusätzlichen Tabelle verfolgen müssen."
Gibt es irgendwelche GOTCHAs, Konsequenzen?
Mit mappedBy , wenn wir nur anrufenperson.getDocuments().add(document)
, die Fremdschlüssel in ID_DOCUMENTS
wird nicht in dem neuen Dokument verknüpft werden, denn dies ist nicht der besitz / nachverfolgt Seite der Beziehung ist!
Um das Dokument mit der neuen Person zu verknüpfen, müssen Sie explizit anrufen document.setPerson(person)
, da dies die besitzende Seite der Beziehung ist.
Bei Verwendung von mappedBy liegt es in der Verantwortung des Entwicklers, die Eigentümerseite zu kennen und die richtige Seite der Beziehung zu aktualisieren, um die Persistenz der neuen Beziehung in der Datenbank auszulösen.