Hibernate是否在setter调用后触发更新查询?

Hibernate是否在setter调用后触发更新查询?,hibernate,Hibernate,给出定义(为简单起见省略ID): 声明如下: a.setB(b); b.setA(a); session.update(a); session.flush(); 我们在刷新中获得PropertyValueException(“NotNull属性引用null或瞬态值”)。但如果我们将“a.setB(b)”与“b.setA(a)”交换,则不会引发异常。这就好像“a.setB(b)”正在使用“b.a”中的空值触发sql更新,而不管下一个setter和update行是什么 我们以前没有这种行为,它显然

给出定义(为简单起见省略ID):

声明如下:

a.setB(b);
b.setA(a);
session.update(a);
session.flush();
我们在刷新中获得PropertyValueException(“NotNull属性引用null或瞬态值”)。但如果我们将“a.setB(b)”与“b.setA(a)”交换,则不会引发异常。这就好像“a.setB(b)”正在使用“b.a”中的空值触发sql更新,而不管下一个setter和update行是什么

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


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

我认为您之所以得到这些语句,是因为“ortransient值”。确保正确地从数据库中获取了
B
的实例,或者告诉Hibernate也保存它(通过显式调用
persist()
/
update()
),或者通过创建级联关系Hibernate不会在setter本身之后启动查询,而是在刷新之后启动查询

在我的例子中,刷新是由“a.setB(b)”之后的读取操作触发的(而实体处于不一致的状态:b.a==null),因为我在hibernate中将flushMode设置为AUTO

我有两种方法来修复它:

  • 当状态一致时,将读取操作移到“b.setA(a)”之后; 或
  • 将flushMode设置为提交


  • 有一些自动刷新设置。。。我现在记不起来了,但我总是在每次DML查询后刷新。我的刷新模式是自动的。我尝试更改提交,但问题仍然存在。实际上,我在web.xml()中的“openSessionInViewFilter”中设置了flushMode,但没有成功。这次我是在sessionFactory.getCurrentSession()之后以编程方式完成的,并且没有抛出异常。我试图了解您是如何解决这个问题的,A和B之间有什么关系?是一对一吗?你在
    的回答中所说的
    find
    是什么意思?在我的例子中,find after
    将find移动到after
    和`注意,现在你必须在每次查找之前手动刷新'?因为在hibernate会话接口中没有find方法。在这种情况下,过时的数据是如何出现的?你能详细说明一下吗?你完全正确。我已经添加了定义关系的注释,现在就更有意义了。“查找”是指“读取操作”。关于flushMode和陈旧数据,我认为这可以很好地解释它:。谢谢你指出这些事情。
    a.setB(b);
    b.setA(a);
    session.update(a);
    session.flush();
    
    Session session = sessionFactory.getCurrentSession();
    session.setFlushMode(FlushMode.COMMIT);