Htelnate在设置者调用后是否会触发更新查询?

时间:2014-09-22 13:17:01

标签: hibernate

鉴于定义(为简单起见省略了id):

@Entity
class A {
   @OneToMany(mappedBy="a", cascade=CascadeType.ALL)
   B b;
}

@Entity    
class B {
   @ManyToOne
   @JoinColumn(nullable=false)
   A a;
}

声明:

a.setB(b);
b.setA(a);
session.update(a);
session.flush();

我们在flush中获取PropertyValueException(“not-null属性引用null或transient值”)。但是如果我们将“a.setB(b)”与“b.setA(a)”交换,则不会抛出任何异常。就好像“a.setB(b)”在“b.a”中触发带有空值的sql更新一样,无论下一个setter和update行如何。

之前我们没有得到这种行为,它显然是从hibernate v3.6转移到v4.3之后开始的。 hibernate如何根据实体和会话中的实体状态更改或方法调用来决定生成sql更新?是否有我可以设置的配置将其更改为以前的行为?

注意:这些语句是简化的,它们之间有更多的代码。

2 个答案:

答案 0 :(得分:1)

Hibernate在设置器本身之后但是在刷新之后不会触发查询。

在我的情况下,在" a.setB(b)"之后,读取操作触发了刷新。 (当实体处于不一致状态时:b.a == null)因为我在休眠时将flushMode设置为AUTO。

我有两种解决方法:

  1. 当状态一致时,将读取操作移至" b.setA(a)"之后; 或
  2. 将flushMode设置为COMMIT。 Note that you now have to manually flush before every db operation involving entities updated earlier in the same transaction or you might get stale data.

    Session session = sessionFactory.getCurrentSession();
    session.setFlushMode(FlushMode.COMMIT);
    

答案 1 :(得分:0)

我认为你是因为"或瞬态值"而得到这个。确保您从数据库中正确地获取了B的实例,或者您告诉Hibernate也保存它(通过显式调用persist() / update())或创建级联关系