Pourquoi la notion d'un côté propriétaire est-elle nécessaire :
L'idée d'un côté propriétaire d'une relation bidirectionnelle vient du fait que dans les bases de données relationnelles il n'y a pas de relations bidirectionnelles comme dans le cas des objets. Dans les bases de données, nous n'avons que des relations unidirectionnelles - les clés étrangères.
Quelle est la raison de l'appellation "côté propriétaire" ?
Le côté propriétaire de la relation suivie par Hibernate est le côté de la relation qui possède la clé étrangère dans la base de données.
Quel est le problème que la notion de côté propriétaire résout ?
Prenons l'exemple de deux entités mises en correspondance sans déclarer un côté propriétaire :
@Entity
@Table(name="PERSONS")
public class Person {
@OneToMany
private List<IdDocument> idDocuments;
}
@Entity
@Table(name="ID_DOCUMENTS")
public class IdDocument {
@ManyToOne
private Person person;
}
D'un point de vue OO, ce mappage définit non pas une relation bidirectionnelle, mais deux des relations unidirectionnelles distinctes.
La cartographie créerait non seulement des tables PERSONS
y ID_DOCUMENTS
mais créerait également une troisième table d'association 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)
)
Remarquez la clé primaire pk
sur ID_DOCUMENTS
seulement. Dans ce cas, Hibernate suit les deux côtés de la relation indépendamment : Si vous ajoutez un document à la relation Person.idDocuments
il insère un enregistrement dans la table d'association PERSON_ID_DOCUMENTS
.
D'autre part, si nous appelons idDocument.setPerson(person)
nous changeons la clé étrangère person_id sur la table ID_DOCUMENTS
. Hibernate crée deux des relations unidirectionnelles (clés étrangères) sur la base de données, pour mettre en œuvre les éléments suivants un relation d'objet bidirectionnelle.
Comment la notion de propriété d'un côté résout le problème :
Souvent, ce que nous voulons est seulement une clé étrangère sur la table ID_DOCUMENTS
vers PERSONS
et non la table d'association supplémentaire.
Pour résoudre ce problème, nous devons configurer Hibernate pour qu'il cesse de suivre les modifications de la relation. Person.idDocuments
. Hibernate ne devrait suivre que les autre côté de la relation IdDocument.person
et pour ce faire, nous ajoutons mappedBy :
@OneToMany(mappedBy="person")
private List<IdDocument> idDocuments;
Qu'est-ce que cela signifie "mappedBy" ?
Cela signifie quelque chose comme : "les modifications de ce côté de la relation sont déjà Cartographié par l'autre côté de la relation IdDocument.person, donc pas besoin de de le suivre ici séparément dans une table supplémentaire."
Y a-t-il des GOTCHAs, des conséquences ?
Utilisation de mappedBy Si on appelle seulement person.getDocuments().add(document)
la clé étrangère dans ID_DOCUMENTS
sera PAS être lié au nouveau document, car ce n'est pas le côté propriétaire/suivi de la relation !
Pour lier le document à la nouvelle personne, vous devez explicitement appeler document.setPerson(person)
parce que c'est la côté propriétaire de la relation.
Lorsque vous utilisez mappedBy Dans ce cas, il incombe au développeur de savoir quel est le côté propriétaire, et de mettre à jour le côté correct de la relation afin de déclencher la persistance de la nouvelle relation dans la base de données.
1 votes
stackoverflow.com/questions/12493865/
10 votes
J'étais perdue jusqu'à ce que je lise ceci : javacodegeeks.com/2013/04/
5 votes
La table de la BD avec la colonne de la clé étrangère est traitée comme le côté propriétaire. Ainsi, l'entité commerciale représentant cette table de base de données est le propriétaire (côté propriétaire) de cette relation. Pas nécessairement, mais dans la plupart des cas, le côté propriétaire aura l'annotation @JoinColumn.