它们之间的区别是什么:
@Entity
public class Company {
@OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY)
@JoinColumn(name = "companyIdRef", referencedColumnName = "companyId")
private List<Branch> branches;
...
}和
@Entity
public class Company {
@OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY,
mappedBy = "companyIdRef")
private List<Branch> branches;
...
}发布于 2012-08-14 01:10:56
@JoinColumn 可以在关系的两端使用。问题是关于在@OneToMany端使用@JoinColumn (罕见的情况)。这里的重点是物理信息重复(列名)以及未优化的SQL查询,这将产生一些额外的UPDATE语句。
根据documentation的说法
由于many to one是(几乎)在JPA规范中总是双向关系的所有者端,所以一对多关联由@OneToMany(mappedBy=...)注释
@Entity
public class Troop {
@OneToMany(mappedBy="troop")
public Set<Soldier> getSoldiers() {
...
}
@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk")
public Troop getTroop() {
...
} 通过部队属性,Troop与Soldier具有双向的一对多关系。您不必(一定不能)在mappedBy端定义任何物理映射。
要映射一个双向的一对多,将一对多作为拥有方的,您必须删除mappedBy元素,并将多对一@JoinColumn设置为insertable,将updatable设置为false。此解决方案未经过优化,并将生成一些额外的UPDATE语句。
@Entity
public class Troop {
@OneToMany
@JoinColumn(name="troop_fk") //we need to duplicate the physical information
public Set<Soldier> getSoldiers() {
...
}
@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk", insertable=false, updatable=false)
public Troop getTroop() {
...
}发布于 2012-08-14 00:20:09
注释@JoinColumn表明此实体是关系的所有者(即:对应的表有一个列,该列具有指向被引用表的外键),而属性mappedBy表明这一端的实体是关系的反面,并且所有者驻留在"other“实体中。这也意味着您可以从使用"mappedBy“(全双向关系)注释的类中访问另一个表。
特别是,对于问题中的代码,正确的注释将如下所示:
@Entity
public class Company {
@OneToMany(mappedBy = "company",
orphanRemoval = true,
fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
private List<Branch> branches;
}
@Entity
public class Branch {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "companyId")
private Company company;
}发布于 2018-06-27 13:55:04
单向一对多关联
如果将@OneToMany注释与@JoinColumn一起使用,则会有一个单向关联,如下图中父Post实体和子PostComment之间的关联:

当使用单向一对多关联时,只有父端映射该关联。
在此示例中,仅Post实体将定义到子PostComment实体的@OneToMany关联:
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();双向一对多关联
如果使用具有mappedBy属性集的@OneToMany,则具有双向关联。在我们的示例中,两个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<>();@OneToMany注释的mappedBy属性引用了子PostComment实体中的post属性,通过这种方式,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不能保证关联状态更改将传播到数据库。
选择哪一个?
单向@OneToMany关联的性能不是很好,因此您应该避免使用它。
您最好使用效率更高的双向@OneToMany。
https://stackoverflow.com/questions/11938253
复制相似问题