我正在使用 EXTENDED 持久上下文,因为它允许我在对象上加载一对多关系,并且在我“合并”一个对象之前也不需要SELECT持久的背景。
我有一个DummyObject:
“上次更新”日期字段
一对多关系
通过em.merge(DummyObject)
调用,在一个JVM中每 5 秒更新此对象。
在另一个JVM中,我查询DummyObject进行如下调用
em.createQuery("from DummyObject").getResultList();
我每隔 5 秒也会执行此查询。
问题是,即使Hibernate生成了正确的SQL语句(当我有语句登录时),查询产生的对象都有连续调用后第一个查询的时间戳,而数据库是正确获取更新(我已经验证)。
我也试过@Version的各种乐观锁定无济于事。 (见评论)
另一件事是,这在以下情况下可以正常工作:
我更改了PersistentContextType 到 TRANSACTIONAL (某事 不会允许我懒洋洋地加载 一对多的关系)
我做了一个EntityManager.clear()调用 在我执行上面的查询之前 (也是不允许的 我懒洋洋地加载了ONE-MANY 关系)。
为什么我的查询会返回陈旧数据?我已启用否二级缓存或查询缓存。
我做错了吗?我可以通过query.setHint(,)设置一些内容吗?
也许我不理解“扩展”与 TRANSACTIONAL 正确无误。
答案 0 :(得分:1)
hibernate会话正在缓存持久对象。因此,由于您要在一个JVM(A)中进行修改并在另一个JVM(B)中进行读取,因此需要刷新B的会话以查看更改。您可以打开新会话或逐出/刷新持久对象。您还可以跨两个JVM复制会话,这可能会解决您的问题。或者您可以尝试将查询更改为仅返回您需要的“DummyObject”部分,并仅在需要时读取持久对象。您也可以尝试无状态会话。
答案 1 :(得分:0)
你在尝试之前尝试过刷新()吗?
答案 2 :(得分:0)
有趣。对我而言,似乎持久化上下文中的实体实例未使用查询结果进行更新。这可能是设计的 - 您可能会通过执行查询而意外覆盖本地更改。
更糟糕的是,JPA无法分离单个实例。您可以清除整个上下文,也可以不清除。所以这也不是一个可能的解决方案。
refresh()
类中有一个PersistanceContext
方法可以从数据库中获取更改并相应地更新实体实例。但我可以看到这在实际实现中可能不适用。所以我的答案结果是:你可能无法让它发挥作用。