Vì đây là một câu hỏi rất phổ biến, tôi đã viết
bài viết này , trên đó câu trả lời này dựa trên.
Hiệp hội một-nhiều-hướng
Như tôi đã giải thích trong bài viết này , nếu bạn sử dụng @OneToManychú thích với @JoinColumn, thì bạn có một liên kết đơn hướng, giống như liên kết giữa Postthực thể cha mẹ và con PostCommenttrong sơ đồ sau:

Khi sử dụng liên kết một-nhiều-hướng, chỉ có phía cha mẹ ánh xạ liên kết.
Trong ví dụ này, chỉ có Postthực thể sẽ xác định một @OneToManyliên kết đến PostCommentthực thể con :
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();
Hiệp hội một-nhiều-hai chiều
Nếu bạn sử dụng @OneToManyvới tập mappedBythuộc tính, bạn có một liên kết hai chiều. Trong trường hợp của chúng tôi, cả hai Postthực thể đều có một tập hợp các PostCommentthực thể con và PostCommentthực thể con có một tham chiếu trở lại Postthực thể cha , như được minh họa bằng sơ đồ sau:

Trong PostCommentthực thể, thuộc tính postthực thể được ánh xạ như sau:
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
Lý do chúng tôi đặt fetchthuộc tính rõ ràng FetchType.LAZYlà vì theo mặc định, tất cả @ManyToOnevà các @OneToOneliên kết được tìm nạp một cách háo hức, điều này có thể gây ra sự cố truy vấn N + 1. Để biết thêm chi tiết về chủ đề này, hãy xem bài viết này .
Trong Postthực thể, commentshiệp hội được ánh xạ như sau:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
Các mappedBythuộc tính của @OneToManytài liệu tham khảo chú thích các posttài sản ở trẻ em PostCommenttổ chức nào, và, theo cách này, Hibernate biết rằng sự liên kết hai chiều được điều khiển bởi các @ManyToOnebên, trong đó có trách nhiệm quản lý các giá trị cột Ngoại chính mối quan hệ bảng này được dựa trên.
Đối với một hiệp hội hai chiều, bạn cũng cần có hai phương thức tiện ích, như addChildvà removeChild:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
Hai phương pháp này đảm bảo rằng cả hai mặt của hiệp hội hai chiều không đồng bộ. Không đồng bộ hóa cả hai đầu, Hibernate không đảm bảo rằng các thay đổi trạng thái kết hợp sẽ lan truyền đến cơ sở dữ liệu.
Để biết thêm chi tiết về wat tốt nhất để đồng bộ hóa các hiệp hội hai chiều với JPA và Hibernate, hãy xem bài viết này .
Chọn cái nào?
Các theo một hướng @OneToManyliên kết không thực hiện rất tốt , vì vậy bạn nên tránh nó.
Bạn nên sử dụng hai chiều @OneToManysẽ hiệu quả hơn .