Da dies eine sehr häufige Frage ist, habe ich
diesen Artikel geschrieben , auf dem diese Antwort basiert.
Unidirektionale Eins-zu-Viele-Assoziation
Wie ich in diesem Artikel erklärt habe , haben Sie, wenn Sie die @OneToMany
Annotation mit verwenden @JoinColumn
, eine unidirektionale Zuordnung, wie die zwischen der übergeordneten Post
Entität und dem untergeordneten Element PostComment
in der folgenden Abbildung:
Bei Verwendung einer unidirektionalen Eins-zu-Viele-Zuordnung ordnet nur die übergeordnete Seite die Zuordnung zu.
In diesem Beispiel Post
definiert nur die Entität eine @OneToMany
Zuordnung zur untergeordneten PostComment
Entität:
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();
Bidirektionale Eins-zu-Viele-Assoziation
Wenn Sie das @OneToMany
mit dem mappedBy
Attributsatz verwenden, haben Sie eine bidirektionale Zuordnung. In unserem Fall verfügt sowohl die Post
Entität über eine Sammlung von PostComment
untergeordneten Entitäten als auch die untergeordnete PostComment
Entität über einen Verweis auf die übergeordnete Post
Entität, wie in der folgenden Abbildung dargestellt:
In der PostComment
Entität wird die post
Entitätseigenschaft wie folgt zugeordnet:
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
Der Grund, warum wir das fetch
Attribut explizit festlegen , FetchType.LAZY
ist, dass standardmäßig alle @ManyToOne
und @OneToOne
Zuordnungen eifrig abgerufen werden, was zu N + 1-Abfrageproblemen führen kann. Weitere Informationen zu diesem Thema finden Sie in diesem Artikel .
In der Post
Entität wird die comments
Zuordnung wie folgt zugeordnet:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
Das mappedBy
Attribut der @OneToMany
Annotation verweist auf die post
Eigenschaft in der untergeordneten PostComment
Entität. Auf diese Weise weiß Hibernate, dass die bidirektionale Zuordnung von der @ManyToOne
Seite gesteuert wird , die für die Verwaltung des Spaltenwerts für den Fremdschlüssel verantwortlich ist, auf dem diese Tabellenbeziehung basiert.
Für eine bidirektionale Zuordnung benötigen Sie außerdem zwei Dienstprogrammmethoden wie addChild
und removeChild
:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
Diese beiden Methoden stellen sicher, dass beide Seiten der bidirektionalen Zuordnung nicht synchron sind. Ohne beide Enden zu synchronisieren, garantiert Hibernate nicht, dass Änderungen des Zuordnungsstatus in die Datenbank übertragen werden.
Weitere Informationen zum besten Wat zum Synchronisieren bidirektionaler Zuordnungen mit JPA und Hibernate finden Sie in diesem Artikel .
Welches soll ich wählen?
Die unidirektionale @OneToMany
Zuordnung funktioniert nicht sehr gut , daher sollten Sie sie vermeiden.
Sie sind besser dran, wenn Sie das bidirektionale verwenden, @OneToMany
das effizienter ist .