2 回答
TA贡献1871条经验 获得超8个赞
您正在混合本机 SQL 和休眠。基本上,当您第一次检索实体时,它会存储在您的会话 EntityManager 中。然后您使用纯 SQL 更新数据库中的行,但就休眠而言,实体并没有被弄脏,因为它不够聪明,无法理解纯 SQL 与对象模型的关系。当你第二次检索它时,它只是给你它已经缓存在 EntityManager 中的原始实体,而不是查询数据库。
解决方案是在更新后简单地从 EntityManager 中手动强制驱逐实体,如下所示: sessionFactory.getCurrentSession().evict(entity);
或者您可以简单地更新您获取的实体并将其持久化(最佳解决方案恕我直言,没有多余的 DAO 方法,以及远离数据库的最佳抽象):
ExampleEntity entity = (ExampleEntity) sessionFactory.getCurrentSession().createCriteria(ExampleEntity.class).add(Restrictions.eq("id", 190001L)).uniqueResult();
entity.setState(State.CLOSED);
entity.setVersion(e.getVersion() + 1);
sessionFactory.getCurrentSession().update(entity);
基本上...无论您选择哪个选项,都不要在同一事务中混合使用纯 SQL 和休眠查询。一旦 hibernate 加载了一个对象,它将从其缓存中返回相同的实体,直到它知道它是脏的。当使用纯 SQL 弄脏实体时,知道实体是脏的还不够聪明。如果您别无选择并且必须使用 SQL(在设计良好的休眠模型中永远不会出现这种情况),则调用 evict 来告诉休眠实体是脏的。
添加回答
举报