【问题标题】:Are entities cached in jpa by default?默认情况下,实体是否缓存在 jpa 中?
【发布时间】:2011-02-12 01:38:33
【问题描述】:

我将实体添加到我的数据库中,它工作正常。但是当我检索列表时,我得到了旧实体,我添加的新实体在我取消部署应用程序并再次重新部署之前不会显示。这意味着我的实体是否默认缓存?但是,我没有在我的 persistence.xml 或任何此类文件中对缓存实体进行任何设置。

我什至尝试过调用flush()、refresh() 和merge()。但它仍然只显示旧实体。我错过了什么吗?请帮帮我。

【问题讨论】:

    标签: java jpa second-level-cache toplink-essentials


    【解决方案1】:

    欢迎来到 JPA。如果您使用它,则意味着如果您在 JPA 之外更新数据库,除非您知道自己在做什么并且非常小心,否则您将遇到巨大的问题。这意味着您必须弄清楚如何刷新任何缓存的实体,以便重新加载它们。

    基本上,如果您能提供帮助,请不要更新 JPA 之外的实体,如果您这样做了,您可能需要了解特定 JPA 提供者使用的缓存模型的工作原理。如果您需要在 JPA 之外进行大量更新,那么 JPA 可能不是您的正确选择。

    【讨论】:

    • 但是我没有在 JPA 之外更新数据库。我使用了 jpa 的持久化方法,并在数据库中看到了记录。但是当我检索列表时,我没有看到新添加的实体。请帮帮我。
    • 此外,更奇怪的是,如果我将提供程序从 TopLink 更改为 EclipseLink,一切正常!使用 TopLink 时,只会出现这个问题。我正在使用 Netbeans 6.8 和 Glassfish v3。
    • 我没有使用任何使用 entitymanager.getTransaaction 的事务或任何容器管理的事务。我可以在数据库中看到记录,但在我检索的列表中看不到。基本上,发生的事情是说有员工和部门表。部门表有员工集合。因此,如果我保留员工记录,那么它会出现在数据库中,但不会出现在部门的员工集合中,直到我明确地将其添加到员工集合中。这是必要的步骤吗?如果我有 10 个与一个实体相关的表。我必须将它添加到所有 10 个表的集合中吗?太乏味了?
    • @Nitesh 哦,不同的问题。是的,您绝对必须通过将 Java 对象放入该集合来管理它。
    • @Nitesh 这是另一种方式:您更新对象并更新数据库以反映这一点。您必须考虑是否希望您的一对多关系也是单向或双向的。仅仅因为您可以在一侧拥有一组实体并不意味着您应该这样做。
    【解决方案2】:

    这意味着我的实体是否默认缓存?

    JPA 1.0 没有定义 L2 缓存(“共享缓存”),JPA 1.0 只定义了 L1 缓存(“事务缓存”),但 JPA 提供者可以支持共享对象缓存,大多数都这样做。 TopLink Essentials 就是这种情况,它通过JPA Extensions for Caching(每个 JVM)支持 L1 和 L2 缓存。

    现在,正如伟大的文章 Understanding the cache of TopLink Essentials(GlassFish JPA) 中所解释的那样:

    • 来自同一持久性单元的所有 EntityManager 共享会话缓存(TopLink 就是这样调用二级缓存的)。
    • 默认开启会话缓存。
    • 如果在持久化上下文中有实体的修改/删除,它们会在事务提交后同步到会话缓存,因此会话缓存的状态会更新(或者这样的缓存根本不可用)。

    所以你的设置肯定有其他问题。您可以尝试通过添加以下属性来禁用共享会话缓存以用于测试目的(并且仅用于测试目的):

    <property name="toplink.cache.shared.default" value="false"/>
    

    但如果这有什么改变,我会感到惊讶。正如我所说,我认为还有另一个问题。

    PS:这并不能回答问题,但是,如果您使用的是 GlassFish v3,为什么不使用 EclipseLink?

    更新:回答 OP 的评论

    因此,如果我保留员工记录,那么它会出现在数据库中,但不会出现在部门员工的集合中,直到我明确地将其添加到员工集合中。这是必要的步骤吗?

    好吧,如果你不在 Java 级别创建实体之间的链接,JPA 将无法在数据库中创建它(JPA 只做你告诉他做的事情) .所以,是的,您需要创建链接,并且在双向关联的情况下,您甚至需要设置链接的两侧(例如将employee 添加到员工集合中Department 并设置 departmentEmployee)。

    【讨论】:

    • 嗨 Pascal Thivent,我在我的 persistence.xml 中提供了 EclipseLink,一切正常。但我仍然有另一个疑问,我也要求 cletus :- 基本上,发生的事情是说有员工和部门表。部门表有员工集合。因此,如果我保留员工记录,那么它会出现在数据库中,但不会出现在部门的员工集合中,直到我明确地将其添加到员工集合中。这是必要的步骤吗?如果我有 10 个与一个实体相关的表。我必须将它添加到所有 10 个表的集合中吗?太乏味了?
    【解决方案3】:

    JPA 2.0 定义了共享 (L2) 缓存,但未指定默认值。 EclipseLink 默认启用缓存,其他提供程序不启用。

    在您调用 clear() 或创建新的之前,EntityManager 将始终具有持久性上下文 (L1) 缓存。

    您可以禁用共享缓存,

    见,http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching

    但是你的问题是你没有维护好双方的关系。设置1-1时需要添加到1-m,否则你的对象无效。

    有关缓存的更多信息,请参阅

    http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Caching

    【讨论】:

      【解决方案4】:

      您在使用 EntityManager 吗?如果不试试http://docs.oracle.com/javaee/5/api/javax/persistence/EntityManager.html

      您是否使用数据源来管理与数据库的连接?你也应该试试。是在您的服务器中配置的 xml。提供有关您的架构的更多信息,以便我们为您提供帮助。

      【讨论】:

        【解决方案5】:

        我正在使用eclipselinkejb的上下文,我发现当我查询实体时,它会自动缓存,但我也运行一个函数来更改记录在数据库中,所以我可能会在缓存中获取旧数据,所以我通过将以下内容添加到文件 persistence.xml 来禁用缓存:

        <shared-cache-mode>NONE</shared-cache-mode>
        

        它确实有效!

        【讨论】:

          猜你喜欢
          • 2020-12-20
          • 2018-05-20
          • 1970-01-01
          • 1970-01-01
          • 2023-03-23
          • 1970-01-01
          • 2023-03-15
          • 2021-09-16
          • 1970-01-01
          相关资源
          最近更新 更多