【问题标题】: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 查询,并且不只是尝试从其一级缓存中读取实体?

标签: java hibernate entity


【解决方案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/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 1970-01-01
    • 2018-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多