鉴于定义(为简单起见省略了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更新?是否有我可以设置的配置将其更改为以前的行为?
注意:这些语句是简化的,它们之间有更多的代码。
答案 0 :(得分:1)
Hibernate在设置器本身之后但是在刷新之后不会触发查询。
在我的情况下,在" a.setB(b)"之后,读取操作触发了刷新。 (当实体处于不一致状态时:b.a == null)因为我在休眠时将flushMode设置为AUTO。
我有两种解决方法:
将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()
)或创建级联关系