Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 一对多方作为所有者和不可空外键的双向关联_Java_Hibernate_Jpa_Bidirectional Relation - Fatal编程技术网

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

Java 一对多方作为所有者和不可空外键的双向关联,java,hibernate,jpa,bidirectional-relation,Java,Hibernate,Jpa,Bidirectional Relation,我在建立一对多的双向关联时遇到了问题。我将使用稍微修改过的示例来描述我的问题 @Entity public class Troop { @OneToMany(cascade = CascadeType.ALL) @JoinColumn(name="troop_fk") //we need to duplicate the physical information public Set<Soldier> getSoldiers() { ... } @E

我在建立一对多的双向关联时遇到了问题。我将使用稍微修改过的示例来描述我的问题

@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() {
    ...
} 
问题是,当我们第一次尝试在没有force_fk的情况下插入soldier时,会抛出一个异常,因为该列不可为null

为什么Hibernate不只是将force_fk添加到insert中,而不是稍后使用它更新记录?
有什么方法可以让我做我上面描述的事情吗

问题在于
insertable=false,updateable=false

这明确地告诉Hibernate在插入或更新士兵实体时不要更新
team_fk

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

如果希望能够创建没有部队的士兵,则需要将关联设置为可选:
@ManyToOne(optional=true)


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

摘自JPA 2.0规范,第2.9章实体关系:双向关系的反向侧必须通过使用
onetomone
mappedBy
元素来引用其所属侧,
OneToMany
ManyToMany
注释。
mappedBy
元素指定实体中作为关系所有者的属性或字段。(…)一对多/多对一双向关系的多方必须是拥有方,因此不能在
ManyToOne
注释上指定
mappedBy
元素。我理解,但是从我上面发布的Hibernate文档的链接中可以看到,他们建议您删除mappedBy元素,并按照我的观点在一对多的侧面添加@joincolm:当您持久化部队时,Cascacde ALL将导致JPA首先持久化士兵,即刷新数据库。但那时,你的部队还没有身份证。因此,在插入时没有办法填充U fk。一些数据库支持约束模式,其中约束检查将推迟到提交。这可能会解决你的问题。。但不确定这会带来什么其他问题。从来没有试过。
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