由于这是一个非常常见的问题,因此我写了
这篇文章,此答案基于此。
单向一对多关联
正如我在本文中所解释的,如果将@OneToMany注释与一起使用@JoinColumn,则您将具有单向关联,例如下图中的父Post实体和子实体之间的关联PostComment:

使用单向一对多关联时,只有父侧会映射该关联。
在此示例中,仅Post实体将定义与子实体的@OneToMany关联PostComment:
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();
双向一对多关联
如果@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一面,这是负责管理这个表的关系是基于外键列值。
对于双向关联,您还需要具有两个实用程序方法,例如addChild和removeChild:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
这两种方法可确保双向关联的两端不同步。如果不同步两端,则Hibernate无法保证关联状态更改将传播到数据库。
有关使双向关联与JPA和Hibernate同步的最佳方法的更多详细信息,请参阅本文。
选择哪一个?
该单向@OneToMany协会不执行得很好,所以你应该避免。
您最好使用更高效的双向@OneToMany。