两个实体管理器实例在第一个更新时第二个选择旧值
Posted
技术标签:
【中文标题】两个实体管理器实例在第一个更新时第二个选择旧值【英文标题】:Two entity manager instances when making update in the first one the second one selects the old value 【发布时间】:2012-05-08 09:38:47 【问题描述】:我正在使用休眠实体管理器 3.4.0.GA,但我遇到了流动问题: 我有两个实体管理器实例 em1 和 em2,我有一个实体。我更新 em1 中的实体,然后在 em2 中选择它,但 em2 对数据库进行选择,但在实体中有旧值(更新前)。我做错了什么:(
确切的步骤在 em1 (T1) 我获取实体并更新它然后提交 T1 并且更改在数据库中,然后在 em2 (T2)我进行了获取所有实体的 jpa 查询,但实体(我在 T1 中成功更新)保留了旧值,因为它是从一级缓存中读取的:(。
【问题讨论】:
您是否在同一笔交易中这样做?您是否检查过em2
确实发出了 SQL 查询,并且不只是尝试从其一级缓存中读取实体?
【参考方案1】:
Level - 1 : 这个缓存的范围是EntityManager
或PersistenceContext
(不用于Hibernate,但可能是会话)。
Level - 2:它的作用域是EntityManagerFactory
& 缓存的对象可以被应用程序中的任何实体管理器检索。
当您使用两个不同的实体管理器时,对象不是从一级缓存加载的,而是从二级缓存加载的。因此从中检索过时的对象。
你可以试试session.setCacheMode(CacheMode.REFRESH)
。
否则,您可以在查询本身中设置提示。
@NamedQuery(name="queryWithNoCache",
query="SELECT e FROM Entity e",
hints=@QueryHint(name="org.hibernate.cacheMode", value="REFRESH"))
您也可以相应地尝试其他模式。
Ehcache 文档:
Session.find 不使用主对象的缓存。休眠 将尝试将缓存用于任何关联的对象。会话.find 但是确实会导致缓存被填充。 Query.find 适用于 完全相同的方式。在有机会获得缓存的地方使用这些 命中率低。
【讨论】:
【参考方案2】:更新后尝试使用 em1.flush() :)
【讨论】:
它会刷新 em1 但在 em1 中更新是可以的。我的问题是这个实体是从 em2 中的第一个 lv 缓存加载的 是的,它会更新 em1 中的状态,但 em1 中的状态很好,我想在 em2中刷新它> 但我在那里使用 jpql 查询:( 我不知道..如果您使用命名查询添加“提示”..例如:@NamedQuery(name = "findEmployeesByDepartmentId", query = "select o from Employee o where o. department.id = :departmentId"), hints = @QueryHint(name=QueryHints.REFRESH, value=HintValues.TRUE) 看这里soadev.blogspot.it/2010/02/…以上是关于两个实体管理器实例在第一个更新时第二个选择旧值的主要内容,如果未能解决你的问题,请参考以下文章