与一对多方的双向关联作为所有者和不可为空的外键

时间:2014-05-01 18:06:15

标签: java hibernate jpa bidirectional-relation

我在设置与一对多方作为所有者的双向关联时遇到问题。我将使用Hibernate documentation稍加修改的示例来描述我的问题。

@Entity
public class Troop {
    @OneToMany(cascade = CascadeType.ALL)
    @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, nullable = false)
    public Troop getTroop() {
    ...
} 

据我所知,在数据库世界中,上述关系的所有者将是士兵,因为它具有带外键的列,但是这在现实世界逻辑中没有意义,因为士兵是部队的一部分部队拥有一名士兵。

我希望能够使用CascadeType.ALL在我坚持部队时自动保存所有士兵。

hibernate文档表明:

  

此解决方案未经过优化,将生成其他UPDATE语句。

例如。日志

Insert Into Troop(id) Values(1)
Insert Into Soldier(id) Values(1)
Insert Into Soldier(id) Values(2)

Update Soldier Set troop_fk = 1 Where id = 1
Update Soldier Set troop_fk = 1 Where id = 2

问题在于,当我们首次尝试插入没有troop_fk的士兵时,会抛出异常,因为该列不可为空。

为什么Hibernate不只是将troop_fk添加到插入而不是稍后用它更新记录? 我有办法做我上面描述的事情吗?

1 个答案:

答案 0 :(得分:0)

问题是insertable=false, updatable=false

当插入或更新Soldier实体时,这明确告诉Hibernate NOT 更新troop_fk

但是,如果没有先将其与部队相关联,你仍然无法插入新的士兵实体,因为fk列不可为空。

如果您希望能够在没有部队的情况下创建士兵,那么您需要将关联设为可选:@ManyToOne(optional=true)

我会更改部队的@OneToMany关联以使用mappedBy。在我们系统中的300多个实体中,我们从未在@JoinColumn侧使用@OneToMany