Java JPA/Hibernate查询返回过时的结果
我使用的是扩展的持久上下文,因为它允许我在对象上惰性地加载一个一对多关系,并且在我将对象与持久上下文“合并”之前,它也不需要选择 我有一个DummyObject,带有:Java JPA/Hibernate查询返回过时的结果,java,hibernate,jpa,jakarta-ee,persistence,Java,Hibernate,Jpa,Jakarta Ee,Persistence,我使用的是扩展的持久上下文,因为它允许我在对象上惰性地加载一个一对多关系,并且在我将对象与持久上下文“合并”之前,它也不需要选择 我有一个DummyObject,带有: “上次更新”日期字段 一对多的关系 在一个JVM中,通过em.merge(DummyObject)调用每隔5秒更新一次此对象 在另一个JVM中,我执行如下调用来查询DummyObject em.createQuery("from DummyObject").getResultList(); 我还每隔5秒进行一次此查询 问题
em.merge(DummyObject)
调用每隔5秒更新一次此对象
在另一个JVM中,我执行如下调用来查询DummyObject
em.createQuery("from DummyObject").getResultList();
我还每隔5秒进行一次此查询
问题是,尽管Hibernate正在生成正确的SQL语句(当我登录语句时),并且数据库正在正确地获得更新(我已经验证),但查询产生的对象都具有连续调用后第一次查询的时间戳
我还尝试了@Version的各种乐观锁定,但都没有成功。(见评论)
另一件事是,在以下情况下,这确实可以正常工作:
也许我不太理解“扩展的”与“事务的”。在获取之前是否尝试过刷新?很有趣。在我看来,持久性上下文中的实体实例似乎没有使用查询结果进行更新。这可能是出于设计——您可能会通过执行查询意外地覆盖本地更改 更糟糕的是,在JPA中无法分离单个实例。要么清除整个上下文,要么不清除。因此,这也不是一个可能的解决方案
PersistanceContext
类中提供了一个refresh()
方法,该方法从数据库中获取更改并相应地更新实体实例。但我可以看出,这在实际实现中可能不适用。所以我的答案是:您可能无法让它工作。hibernate会话正在缓存持久对象。因此,因为您在一个JVM(A)中修改,在另一个JVM(B)中读取,所以需要刷新B的会话以查看更改。您可以打开一个新会话,或者逐出/刷新持久对象。您还可以跨两个JVM复制会话,这可能会解决您的问题。或者,您可以尝试将查询更改为仅返回所需的“DummyObject”片段,并且仅在需要时读取持久对象。您也可以尝试无状态会话 上次更新是否映射为版本?刚刚尝试过。没用。我还尝试添加一个显式的“version”字段,并用@version注释它。equals和hashcode正在查看LastUpdate吗?是否看到不属于em.createQuery()结果的其他对象?equals和hashcode基于类的成员。我在结果中没有看到任何其他对象。您是每次都重新获取该对象,还是使用延迟加载的引用?在新数据出现之前,我遇到了需要再次提取对象的问题。我不确定我是否理解你的意思。我每5秒钟执行一次以上的查询,从该查询中得到的结果是陈旧的。这更像是一个“测试”案例,而不是一个实际的实现。基本上,我的问题是,我希望能够使用扩展上下文类型,并且能够惰性地加载关系。但不起作用的是,查询总是返回过时的结果;是的,我看过迭代返回的结果集并对每个对象执行“刷新”,但对于大型结果集来说,这太荒谬了。列表的内容是否保持不变(即,您不会删除新对象或旧对象)?如果我不对列表中的每个对象执行refresh(),列表的内容将保持不变。