2009-06-17 96 views
3

我正在使用EXTENDED持久性上下文,因为它可以让我懒惰地加载对象上的一对多关系,并且在“合并”之前它也不需要SELECT具有持久性上下文的对象。JPA/Hibernate查询返回陈旧结果

我有一个DummyObject:

  1. A “最近更新” 的日期字段

  2. 一个一对多的关系

该对象被更新一次在一个JVM中通过调用em.merge(DummyObject)秒。

在另一个JVM,我查询了DummyObject做类似下面

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

我也是这样做的查询每秒通话。

问题是,即使Hibernate正在生成正确的SQL语句(当我有语句登录时),Query的对象在连续调用后都会有第一个Query的Timestamp,而数据库正确获取更新(我已验证)。

我也尝试了各种乐观锁定与@Version无济于事。 (见注释)

另一件事是,当这并不正常工作:

  1. 我改变PersistentContextType 到TRANSACTIONAL(东西 不会让我懒洋洋地加载 一对多关系)

  2. 我做一个EntityManager.clear()调用 之前我做了以上的查询 (一些也不会允许 我懒洋洋地加载关系的一对多 )。

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

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

也许我不明白 “EXTENDED” 与TRANSACTIONAL正确。

+1

是上次更新映射为版本? – Surya 2009-06-17 18:04:14

+0

刚刚尝试过。没有工作。我也尝试添加一个明确的“版本”字段并用@Version注释它。也没有工作。 – systemoutprintln 2009-06-17 18:19:24

+0

是等于和hashcode看lastUpdated?你是否看到不属于em.createQuery()结果的附加对象? – zmf 2009-06-26 18:01:41

回答

0

你在尝试做一个flush()之前,你的提取?

0

有趣。对我来说,您的持久性上下文中的实体实例似乎没有用查询的结果更新。这可能是设计上的 - 你可能无意中通过执行查询来覆盖本地更改。

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

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

1

hibernate会话正在缓存持久对象。因此,因为您正在修改一个JVM(A)并阅读另一个JVM(B),所以需要刷新B的会话以查看更改。您可以打开一个新的会话或清除/刷新持久对象。您也可以在两个JVM之间复制会话,这可能会解决您的问题。或者您可以尝试更改查询以仅返回您需要的'DummyObject'的片段,并且只在需要时才读取持久对象。你也可以尝试一个无状态的会话。