Ponieważ jest to bardzo częste pytanie, napisałem
ten artykuł , na którym opiera się ta odpowiedź.
Jednokierunkowe połączenie jeden do wielu
Jak wyjaśniłem w tym artykule , jeśli używasz @OneToManyadnotacji z @JoinColumn, to masz jednokierunkowe powiązanie, takie jak to między Postjednostką nadrzędną a dzieckiem PostCommentna poniższym diagramie:

Podczas korzystania z jednokierunkowego powiązania jeden do wielu, tylko strona nadrzędna mapuje powiązanie.
W tym przykładzie tylko Postjednostka zdefiniuje @OneToManypowiązanie z PostCommentjednostką podrzędną :
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();
Dwukierunkowe powiązanie jeden do wielu
Jeśli używasz @OneToManyz mappedByustawionym atrybutem, masz dwukierunkowy stowarzyszenie. W naszym przypadku zarówno Postjednostka ma kolekcję PostCommentjednostek potomnych, jak i PostCommentjednostka potomna ma odwołanie do Postjednostki macierzystej , jak pokazano na poniższym diagramie:

W PostCommentjednostki, postwłasność jednostka jest odwzorowany w sposób następujący:
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
Powodem, dla którego jawnie ustawiliśmy ten fetchatrybut, FetchType.LAZYjest to, że domyślnie wszystkie @ManyToOnei @OneToOneskojarzenia są pobierane z niecierpliwością, co może powodować problemy z zapytaniami N + 1. Więcej informacji na ten temat można znaleźć w tym artykule .
W Postencji commentspowiązanie jest mapowane w następujący sposób:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
mappedByAtrybut z @OneToManyodniesieniami adnotacji postwłasności w dziecięcej PostCommentpodmiotu i, w ten sposób, Hibernate wie, że stowarzyszenie dwukierunkowa jest kontrolowany przez @ManyToOnestronę, która jest odpowiedzialna za zarządzanie wartość kolumny klucz obcy tabela ta relacja jest oparta na.
W przypadku powiązania dwukierunkowego potrzebne są również dwie metody narzędziowe, takie jak addChildi removeChild:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
Te dwie metody zapewniają, że obie strony skojarzenia dwukierunkowego nie są zsynchronizowane. Bez synchronizacji obu końców Hibernacja nie gwarantuje, że zmiany stanu skojarzenia zostaną przeniesione do bazy danych.
Aby uzyskać więcej informacji na temat najlepszego sposobu synchronizowania skojarzeń dwukierunkowych z JPA i Hibernacją, zapoznaj się z tym artykułem .
Który wybrać?
Jednokierunkowy @OneToManystowarzyszenie nie działa bardzo dobrze , więc należy go unikać.
Lepiej jest użyć dwukierunkowego, @OneToManyktóry jest bardziej wydajny .