我正在浏览Hibernate documentation for bidirectional relationship,在文档中说:
例7.21。双向一对多,多对一方作为协会所有者
@Entity
public class Troop {
@OneToMany(mappedBy="troop")
public Set<Soldier> getSoldiers() {
...
}
@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk")
public Troop getTroop() {
...
}
部队与士兵有一对一的双向关系 通过部队财产。您不必(不得)定义任何 mappedBy端的物理映射。
将双向一个映射到多个,将一对多侧作为 拥有方,你必须删除mappedBy元素并设置许多 一个@JoinColumn作为可插入和可更新为false。这个解决方案 未经优化并将生成其他UPDATE语句。
例7.22。与一对多方作为所有者的双向关联
@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() {
...
}
我发现很难理解这一点,因为我是Hibernate的新手。
1)当医生说:
You don't have to (must not) define any physical mapping in the mappedBy side.
2)7.22中的@JoinColumn
具有name
属性的相同值(troop_fk)。我们可以指定不同的值吗?有什么好处和优点在这里设置insertable=false, updatable=false
的缺点?
有人可以解释一下吗?
答案 0 :(得分:3)
它是双向关联。所以,如果一名士兵向一支士兵招手,那么该部队就包含了这名士兵。这只是说同样事情的两种方式。
在Soldier中,您可以告诉如何在数据库中表示关联:使用名为troop_fk的连接列:
@JoinColumn(name="troop_fk")
public Troop getTroop() {
因此,在此双向关联的另一侧重复相同的信息是多余的。你不能这样做。通过说
@OneToMany(mappedBy="troop")
public Set<Soldier> getSoldiers() {
您告诉Hibernate getSoldiers()
是双向关联的反面,并且可以在Soldier.troop
属性上找到此关联的映射方式。
关于你的第二个问题。再次,目标是定义单,但双向关联。您不需要两个不同的外键来映射单个关联。因此,为连接列指定不同的名称是没有意义的:它将创建一个不同的单向关联。
这种做法是一个丑陋的黑客,AFAIK,JPA规范不支持。 JPA规范要求双向OneToMany协会的所有者方是多方。实际上,它创建了两个以相同方式映射的单向关联,并告诉Hibernate(使用insertable = false和updatable = false)在保存实体时忽略其中一个。当从数据库中读取一名士兵时,它将填充soldier.troop,但是在保存士兵时,无论你输入士兵的什么都将被忽略。你应该避免这种做法,恕我直言。