了解Hibernate文档中的双向关系

时间:2014-08-24 09:39:52

标签: java hibernate

我正在浏览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的缺点?

有人可以解释一下吗?

1 个答案:

答案 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,但是在保存士兵时,无论你输入士兵的什么都将被忽略。你应该避免这种做法,恕我直言。