【问题标题】:Invalidating JPA EntityManager session使 JPA EntityManager 会话无效
【发布时间】:2011-01-24 22:03:21
【问题描述】:

我正在处理的一个项目使用 Spring 2.5 和 JPA 以及 Hibernate 作为提供程序。

我的 DAO 类扩展了 JpaDaoSupport,所以我使用 getJpaTemplate() 方法获取我的 JpaTemplate。

后端数据库可以由我的应用程序或第三方应用程序更改。

当第三方应用程序更改数据库(主要是配置数据更改)时,我需要为我的应用程序的用户提供一种方法来使所有 JPA 会话无效并重新加载新数据(即在后台使所有休眠会话无效) )。这需要我的应用程序的所有并发用户“看到”。

我该怎么做?

【问题讨论】:

    标签: hibernate spring session jpa invalidation


    【解决方案1】:

    有两级缓存:

    • 第一级是 EntityManager 自己的缓存。

      您可以refresh 一个实体,它将从数据库中重新加载,或者您可以clear 实体管理器本身,在这种情况下,所有实体都将从缓存中删除。 JPA 无法从缓存中访问evict only one specific entity。根据您使用的实现,您可以执行此操作,例如Hibernate 的evict 方法。

    • 二级缓存是全局缓存。

      JPA 1.0 不提供对二级缓存的支持。然后,您需要依赖底层的特定实现,或者禁用它。 JPA 2.0 will address this issue 带有 @Cache 注释和缓存 API。您可以使用 Hibernate 特定的 API 清除二级缓存,例如SessionFactory.evict(...).

    缓存的高级问题是:

    • 查询缓存

      可以缓存某些查询的结果。在 JPA 1.0 中再次不支持它,但大多数实现都有方法来指定将缓存哪些查询以及如何缓存。

    • 聚类

      随之而来的还有在集群中的节点之间同步缓存的繁琐问题。在这种情况下,这主要取决于所使用的缓存技术,例如JBoss 缓存。

    您的问题在某种程度上仍然是通用的,答案将取决于您到底在做什么。

    我在一个系统上工作,许多更新无需通过休眠即可完成,我们最终禁用了二级缓存。

    但您也可以跟踪所有打开的会话,并在必要时逐出所有打开的会话的所有第一级缓存以及第二级缓存。您仍然需要自己管理同步,但我想这是可能的。

    【讨论】:

    • getJpaTemplate().getEntityManager().clear() 成功了。谢谢!
    【解决方案2】:

    从架构的角度来看,让其他应用程序绕过您的所有业务逻辑并修改持久数据并不是一个好主意。它使您的应用程序脚下的地面在很多方面都摇摇欲坠:)

    以更优雅的方式与其他系统集成不是一个好主意,例如通过消息处理或批处理。 Spring 对这两者都有很好的支持。

    【讨论】:

    • 缓存失效的问题仍然存在,例如批量处理和批量更新。
    • 是的,所以我会说以这样一种方式进行批处理,即它会为那些需要失效的对象触发事件。 Spring Integration 和 Spring Batch 的结合非常适合这一点。有趣的谈话:infoq.com/presentations/Automating-Operations
    猜你喜欢
    • 2012-09-08
    • 2013-07-07
    • 1970-01-01
    • 2018-03-21
    • 2012-02-03
    • 2016-08-26
    • 1970-01-01
    • 2017-01-30
    相关资源
    最近更新 更多