【问题标题】:JPA EntityManager cachingJPA EntityManager 缓存
【发布时间】:2012-02-11 07:12:40
【问题描述】:

我有一个实体定义如下:

public class Version {
    @Id
    private Long id;
    private String content;
    @Transient
    private Model model;

    //...
}

据我所见,当在实体管理器上执行find 操作时,它只会在底层数据库上创建一次SELECT,然后将实体缓存在实体管理器中。但是,我看到如果我将 Model 分配给 model 属性,则此更改不会反映到缓存的实体。例如。如果在一次调用中完成了find 操作并分配了Model,当我再次从另一个EJB 执行find 时,model 属性又是null。此更改是否未反映到缓存实体?也许是因为它是@Transient?

【问题讨论】:

    标签: java jpa entitymanager


    【解决方案1】:

    实体管理器维护一个一级缓存,一旦事务结束,这个一级缓存就会被丢弃。否则,缓存将返回陈旧的值,因为同一应用程序或另一个应用程序中的其他事务可能会修改或删除缓存的实体。

    此外,每个并发事务都有自己的会话级缓存,因此也有自己的同一实体实例。

    如果在后续事务中,您find同一个实体,将发出新的SQL查询,并返回该实体的不同实例。

    如果必须在给定实体的事务中记住某些内容,则应将其永久保存在数据库中。这就是数据库的意义所在。

    【讨论】:

    • 谢谢,但我没有看到在第二次 EJB 调用时发出新的 SQL 查询(日志记录级别设置为 FINEST)。事务管理设置为默认值。可能是什么原因?
    • EJB1 调用 EJB2,还是有客户端调用 EJB1,然后客户端调用 EJB2?你了解什么是交易,什么时候开始,什么时候结束?
    • 只有一个通过Web服务调用的EJB。对同一方法进行两次连续的 Web 服务调用。在第一次通话中,我在日志中看到了 SELECT 查询。在第二次通话中,没有任何查询。
    • 那么要么你的 JPA 引擎没有记录所有的查询,要么你正在使用二级缓存。无论如何,我的观点仍然存在:您有两个不同的交易,因此您可以保证获得 2 个不同的实体实例。您的瞬态字段应为 null。
    • 能否请您发布您的配置(至少您正在使用的服务器名称、版本和 JPA 实现)?
    【解决方案2】:

    我不得不不同意@JB Nizet。 JPA 的 EntityManager 和 Hibernate 的 Session 提供了扩展的持久性上下文。 “事务一结束就扔掉一级缓存”,这根本不是真的。

    Persistence Context 可以是 Transaction Scoped-- Persistence 上下文“存在”事务的长度,或扩展—— 持久性上下文跨越多个事务。

    https://web.archive.org/web/20131212234524/https://blogs.oracle.com/carolmcdonald/entry/jpa_caching

    但是解决方案是正确的,如果您希望在缓存中更改对象,则必须保留对对象的更改。

    【讨论】:

      【解决方案3】:

      如果您使用的是 EclipseLink,则可以通过两种方式配置合并到瞬态共享缓存中。

      如果使用@CloneCopyPolicy,则持久化上下文中的对象将被克隆到共享缓存中,并保留瞬态字段。

      如果使用了@InstantiationCopyPolicy,那么将为共享缓存创建一个新实例,并且不会保留瞬态。

      如果您使用编织和字段访问,则默认为@CloneCopyPolicy,否则为@InstantiationCopyPolicy。您也可以使用

      进行配置

      您还可以使用 DescriptorEventListener 和 postMerge/postClone 事件来控制合并到共享缓存中的内容。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-08
        • 2012-04-18
        • 1970-01-01
        • 2023-03-23
        • 2018-01-20
        • 2011-04-29
        • 2023-04-11
        • 1970-01-01
        相关资源
        最近更新 更多