我在设置与一对多方作为所有者的双向关联时遇到问题。我将使用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添加到插入而不是稍后用它更新记录? 我有办法做我上面描述的事情吗?
答案 0 :(得分:0)
问题是insertable=false, updatable=false
。
当插入或更新Soldier实体时,这明确告诉Hibernate NOT 更新troop_fk
。
但是,如果没有先将其与部队相关联,你仍然无法插入新的士兵实体,因为fk列不可为空。
如果您希望能够在没有部队的情况下创建士兵,那么您需要将关联设为可选:@ManyToOne(optional=true)
。
我会更改部队的@OneToMany
关联以使用mappedBy
。在我们系统中的300多个实体中,我们从未在@JoinColumn
侧使用@OneToMany
。