これは非常に一般的な質問であるため、
この回答に基づいてこの記事を作成しました。
単方向の1対多の関連付け
この記事で説明したように、で@OneToMany
アノテーションを使用すると@JoinColumn
、次の図の親Post
エンティティと子の間のような単方向の関連付けができますPostComment
。
単方向の1対多の関連付けを使用する場合、親側のみが関連付けをマップします。
この例では、Post
エンティティのみが子エンティティ@OneToMany
への関連付けを定義しますPostComment
。
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();
双方向の1対多の関連付け
属性セットでを使用する@OneToMany
と、mappedBy
双方向の関連付けができます。この例では、次の図に示すように、両方のPost
エンティティにPostComment
子エンティティのコレクションがあり、子PostComment
エンティティには親Post
エンティティへの参照があります。
PostComment
エンティティ、post
次のようにエンティティのプロパティがマッピングされています。
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
我々が明示的に設定された理由fetch
に属性はFetchType.LAZY
、デフォルトでは、すべてのためである@ManyToOne
と@OneToOne
組合は、N + 1つのクエリ問題を引き起こす可能性が、熱心にフェッチされます。このトピックの詳細については、こちらの記事をご覧ください。
Post
エンティティ、comments
次のように関連付けがマップされています。
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
アノテーションのmappedBy
属性は子エンティティのプロパティを@OneToMany
参照しpost
ますPostComment
。これにより、Hibernateは双方向の関連付けが@ManyToOne
サイドサイドの関係がこのテーブルの関係のベースとなる外部キー列の値の管理を担当します。
双方向関連について、あなたはまた、2つのユーティリティメソッドを持っている必要がありますようにaddChild
とremoveChild
。
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
これらの2つの方法により、双方向の関連付けの両側が同期されなくなります。両端を同期しないと、Hibernateはアソシエーション状態の変更がデータベースに伝播することを保証しません。
双方向の関連付けをJPAおよびHibernateと同期させるのに最適なワットの詳細については、こちらの記事をご覧ください。
どれを選ぶ?
単方向@OneToMany
関連は非常によく実行されません。あなたはそれを避ける必要がありますので、。
より効率的な双方向@OneToMany
を使用する方がよいでしょう。