为什么nullable = false强制将FK放入插入,但没有它它会更新以在JPA / Hibernate中设置FK

时间:2013-05-30 15:18:02

标签: java hibernate jpa

使用JPA注释和hibernate,我们最近遇到了一个单向的onetomany映射,看起来像这样:

@Entity
public class FooOrder extends AbstractEntity{

    @OneToMany(cascade= CascadeType.ALL,orphanRemoval = true)
    @JoinColumn(name = "fooOrderId")
    private List<FooItem> fooItems = new ArrayList<FooItem>();
    public void addFooItem(foo item properties here)
    {
       fooItems.add(fooItem);
    }
}


@Entity
public class FooItem extends AbstractEntity {

   SomeRandomStuffButNoLinkToParent
}

测试代码基本上是这样的:

FooOrder fooOrder = new FooOrder(stuff here);

fooOrder.addFooItem(foo item properties here);

fooOrder = fooOrderRepository.save(fooOrder);

当我们对此运行测试时,我们得到的结果如下:

insert FooOrder(columns here)
insert FooItem(columns here missing the FK to FooOrder)
update FooItem set FooOrderFK to proper key.

但如果我设置@JoinColumn(name = "activeOrderId", nullable = false),那么我的sql看起来像这样:

insert FooOrder(columns here)
insert FooItem(columns here with FK to FooOrder)

为什么hibernate通过更新设置FK,如果它可以为空,但是当它不可为空时在插入中设置它?

1 个答案:

答案 0 :(得分:0)

当外键不能为空时

insert FooOrder(columns here)
insert FooItem(columns here with FK to FooOrder)

是实际执行插入的唯一方法。所以真正的问题是为什么并不总是这样做。

我对此的看法是,使用更新的方式适用于另一方无法工作的时候。

假设我们有一些循环的foreingn关键关系。 A有B的外键 B有A的外键 如果这些外键都不可为空,则可能无法插入此键。 您不能先插入A,因为B的外键不能为空。 B也是如此。

另请注意,我的示例可能会过度简化。这个循环外键可以由任意数量的表引起。

因此,首先插入数据然后添加外键只是在这个更复杂的场景中工作的方式。你的非空约束迫使Hibernate采取另一种方式。对于默认情况,首先插入然后添加键只是他更好的想法。