繁体   English   中英

JPA/Hibernate 查询返回过时的结果

[英]JPA/Hibernate Query Returns Stale Results

我正在使用扩展持久上下文,因为它允许我在 object 上延迟加载一对多关系,并且在我将 object 与持久上下文“合并”之前,它也不需要 SELECT。

我有一个 DummyObject:

  1. “最后更新”日期字段

  2. 一对多关系

这个 Object 通过em.merge(DummyObject)调用在一个 JVM 中每5秒更新一次。

在另一个 JVM 中,我查询 DummyObject 执行如下调用

em.createQuery("from DummyObject").getResultList();  

我也每5秒执行一次此查询。

问题是,即使 Hibernate 正在生成正确的 SQL 语句(当我有语句登录时),查询产生的对象都具有连续调用后第一个查询的时间戳,并且数据库正在获取更新正确(我已经验证)。

我也尝试过使用@Version 进行各种乐观锁定,但均无济于事。 (看评论)

另一件事是,这在以下情况下确实可以正常工作:

  1. 我将 PersistentContextType 更改为TRANSACTIONAL (不允许我延迟加载 ONE-MANY 关系的东西)

  2. 在执行上面的查询之前,我执行了一个 EntityManager.clear() 调用(这也不允许我延迟加载 ONE-MANY 关系)。

为什么我的查询返回陈旧数据? 没有启用二级缓存或查询缓存。

难道我做错了什么? 我可以通过 query.setHint(, ) 设置什么吗?

也许我没有正确理解“ EXTENDED ”与TRANSACTIONAL

hibernate session 正在缓存持久对象。 因此,因为您正在修改一个 JVM (A) 并在另一个 JVM(B) 中读取,所以需要刷新 B 的会话以查看更改。 您可以打开一个新的 session 或逐出/刷新持久对象。 您还可以跨两个 JVM 复制会话,这可能会解决您的问题。 或者您可以尝试更改查询以仅返回您需要的“DummyObject”片段,并且仅在需要时读取持久性 object。 您也可以尝试无状态的 session。

您是否尝试过在获取之前执行 flush()?

有趣的。 在我看来,您的持久性上下文中的实体实例似乎未使用查询结果进行更新。 这可能是设计使然——您可能会通过执行查询不小心覆盖本地更改。

更糟糕的是,JPA 中没有办法分离单个实例。 您要么清除整个上下文,要么不清除。 所以这也不是一个可能的解决方案。

PersistanceContext class 中有一个refresh()方法可用,它从数据库中获取更改并相应地更新实体实例。 但我可以看出这在实际实施中可能不适用。 所以我的回答是:你可能无法让它工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM