Puisque c'est une question très courante, j'ai écrit
cet article , sur lequel cette réponse est basée.
Association un-à-plusieurs unidirectionnelle
Comme je l'ai expliqué dans cet article , si vous utilisez l' @OneToMany
annotation avec @JoinColumn
, vous avez alors une association unidirectionnelle, comme celle entre l' Post
entité parent et l'enfant PostComment
dans le diagramme suivant:
Lorsque vous utilisez une association un-à-plusieurs unidirectionnelle, seul le côté parent mappe l'association.
Dans cet exemple, seule l' Post
entité définira une @OneToMany
association avec l' PostComment
entité enfant :
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();
Association un-à-plusieurs bidirectionnelle
Si vous utilisez le @OneToMany
avec l' mappedBy
ensemble d'attributs, vous avez une association bidirectionnelle. Dans notre cas, l' Post
entité a une collection d' PostComment
entités enfants et l' PostComment
entité enfant a une référence à l' Post
entité parent , comme illustré par le diagramme suivant:
Dans l' PostComment
entité, la post
propriété de l' entité est mappée comme suit:
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
La raison pour laquelle nous définissons explicitement l' fetch
attribut FetchType.LAZY
est que, par défaut, toutes les associations @ManyToOne
et @OneToOne
sont extraites avec impatience, ce qui peut entraîner des problèmes de requête N + 1. Pour plus de détails sur ce sujet, consultez cet article .
Dans l' Post
entité, l' comments
association est mappée comme suit:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
L' mappedBy
attribut de l' @OneToMany
annotation fait référence à la post
propriété dans l' PostComment
entité enfant et, de cette façon, Hibernate sait que l'association bidirectionnelle est contrôlée par le @ManyToOne
côté, qui est chargé de gérer la valeur de colonne de clé étrangère sur laquelle cette relation de table est basée.
Pour une association bidirectionnelle, vous devez également disposer de deux méthodes utilitaires, comme addChild
et removeChild
:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
Ces deux méthodes garantissent que les deux côtés de l'association bidirectionnelle ne sont pas synchronisés. Sans synchronisation des deux extrémités, Hibernate ne garantit pas que les changements d'état d'association se propageront à la base de données.
Pour plus de détails sur le meilleur wat pour synchroniser les associations bidirectionnelles avec JPA et Hibernate, consultez cet article .
Lequel choisir?
L' association unidirectionnelle @OneToMany
ne fonctionne pas très bien , vous devez donc l'éviter.
Il vaut mieux utiliser le bidirectionnel @OneToMany
qui est plus efficace .