Relations de table et relations d'entité
Dans un système de base de données relationnelle, il ne peut y avoir que trois types de relations de table:
- un-à-plusieurs (via une colonne de clé étrangère)
- un-à-un (via une clé primaire partagée)
- plusieurs-à-plusieurs (via une table de liens avec deux clés étrangères référençant deux tables parentes distinctes)
Ainsi, une one-to-many
relation de table se présente comme suit:
Notez que la relation est basée sur la colonne Clé étrangère (par exemple, post_id
) dans la table enfant.
Il existe donc une seule source de vérité lorsqu'il s'agit de gérer une one-to-many
relation de table.
Maintenant, si vous prenez une relation d'entité bidirectionnelle qui correspond à la one-to-many
relation de table que nous avons vue précédemment:
Si vous regardez le diagramme ci-dessus, vous pouvez voir qu'il existe deux façons de gérer cette relation.
Dans l' Post
entité, vous avez la comments
collection:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
Et, dans le PostComment
, l' post
association est mappée comme suit:
@ManyToOne(
fetch = FetchType.LAZY
)
@JoinColumn(name = "post_id")
private Post post;
Donc, vous avez deux côtés qui peuvent changer l'association d'entité:
- En ajoutant une entrée dans la
comments
collection enfant, une nouvelle post_comment
ligne doit être associée à l' post
entité parente via sonpost_id
colonne.
- En définissant la
post
propriété de l' PostComment
entité, la post_id
colonne doit également être mise à jour.
Étant donné qu'il existe deux façons de représenter la colonne de clé étrangère, vous devez définir quelle est la source de vérité lorsqu'il s'agit de traduire le changement d'état d'association en modification de la valeur de la colonne de clé étrangère équivalente.
MappedBy (aka le côté inverse)
L' mappedBy
attribut indique que le @ManyToOne
côté est en charge de la gestion de la colonne de clé étrangère, et la collection est utilisée uniquement pour récupérer les entités enfants et pour mettre en cascade les changements d'état de l'entité parente aux enfants (par exemple, la suppression du parent devrait également supprimer les entités enfants).
Il est appelé le côté inverse car il fait référence à la propriété d'entité enfant qui gère cette relation de table.
Synchronisez les deux côtés d'une association bidirectionnelle
Désormais, même si vous avez défini l' mappedBy
attribut et que l' @ManyToOne
association côté enfant gère la colonne de clé étrangère, vous devez toujours synchroniser les deux côtés de l'association bidirectionnelle.
La meilleure façon de le faire est d'ajouter ces deux méthodes utilitaires:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
Les méthodes addComment
et removeComment
garantissent que les deux côtés sont synchronisés. Donc, si nous ajoutons une entité enfant, l'entité enfant doit pointer vers le parent et l'entité parente doit avoir l'enfant contenu dans la collection enfant.
Pour plus d'informations sur la meilleure façon de synchroniser tous les types d'association d'entités bidirectionnelles, consultez cet article .