web-dev-qa-db-fra.com

Quel est le "côté propriétaire" dans un mappage ORM?

Que signifie exactement le côté propriétaire ? Qu'est-ce qu'une explication avec quelques exemples de mappage ( un à plusieurs, un à un, plusieurs à un )?

Le texte suivant est un extrait de la description de @ OneToOne in Java EE 6 Vous pouvez y voir le concept côté propriétaire .

Définit une association à valeur unique avec une autre entité qui a une multiplicité un à un. Il n'est normalement pas nécessaire de spécifier explicitement l'entité cible associée, car elle peut généralement être déduite du type de l'objet référencé. Si la relation est bidirectionnelle, le côté non propriétaire doit utiliser l'élément mappedBy de l'annotation OneToOne pour spécifier le champ de relation ou propriété du côté propriétaire.

114
Just a learner

Vous pouvez imaginer que le côté propriétaire est l'entité qui a la référence à l'autre. Dans votre extrait, vous avez une relation un à un. Puisqu'il s'agit d'une relation symétrique , vous finirez par avoir cela si l'objet A est en relation avec l'objet B alors l'inverse est également vrai.

Cela signifie que l'enregistrement dans l'objet A d'une référence à l'objet B et l'enregistrement dans l'objet B d'une référence à l'objet A seront redondants: c'est pourquoi vous choisissez quel objet "possède" l'autre ayant la référence.

Lorsque vous avez une relation un-à-plusieurs, les objets liés à la partie "plusieurs" seront le côté propriétaire, sinon vous devrez stocker de nombreuses références d'un seul objet à une multitude. Pour éviter cela, chaque objet de la deuxième classe aura un pointeur sur le seul auquel ils se réfèrent (ils sont donc le côté propriétaire).

Pour une relation plusieurs-à-plusieurs, puisque vous aurez de toute façon besoin d'une table de mappage distincte, il n'y aura pas de côté propriétaire.

En conclusion, le côté propriétaire est l'entité qui a la référence à l'autre.

133
Jack

Pourquoi la notion de 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 - des clés étrangères.

Quelle est la raison du nom 'côté propriétaire'?

Le côté propriétaire de la relation suivie par Hibernate est le côté de la relation que possède la clé étrangère dans la base de données.

Quel est le problème résolu par la notion de propriétaire?

Prenons un exemple de deux entités mappées 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 cette cartographie définit non pas une relation bidirectionnelle, mais deux relations unidirectionnelles distinctes .

Le mappage créerait non seulement des tables PERSONS et 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)
)

Notez la clé primaire pk sur ID_DOCUMENTS Uniquement. 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.

En revanche, si nous appelons idDocument.setPerson(person), nous changeons la clé étrangère person_id sur la table ID_DOCUMENTS. Hibernate crée deux relations unidirectionnelles (clé étrangère) sur la base de données, pour implémenter une relation d'objet bidirectionnelle.

Comment la notion de côté propriétaire résout le problème:

Plusieurs fois, ce que nous voulons, c'est seulement une clé étrangère sur la table ID_DOCUMENTS Vers PERSONSet la table d'association supplémentaire.

Pour résoudre ce problème, nous devons configurer Hibernate pour arrêter le suivi des modifications sur la relation Person.idDocuments. Hibernate ne devrait suivre que l'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à Mappé par de l'autre côté de la relation IdDocument.person, donc pas besoin de la suivre ici séparément dans un tableau supplémentaire."

Y a-t-il des GOTCHA, des conséquences?

En utilisant mappedBy, si nous appelons uniquement 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 appeler explicitement document.setPerson(person), car c'est le côté propriétaire de la relation.

Lors de l'utilisation de mappedBy, il est de la responsabilité du 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.

163
Angular University