【问题标题】:How to disable hibernate caching如何禁用休眠缓存
【发布时间】:2011-04-19 04:01:38
【问题描述】:

我正在尝试编写一个单元测试类,它必须使用相同的查询在相同的测试方法中两次从数据库中获取结果。但是由于第二次启用 Hibernate 缓存,它实际上并没有访问数据库,只是从缓存中获取结果。

有人可以回答如何在persistence.xml 中禁用缓存。

我尝试通过更改属性hibernate.cache.use.query_cache = falsehibernate.cache.use_second_level_cache = false 来禁用。

但它没有用。

【问题讨论】:

  • 您是否尝试在同一个会话中完成两个读取?如果是这样,则预期一级缓存会出现此行为。没有看到你的测试用例,很难给你一个准确的答案

标签: hibernate caching


【解决方案1】:

有人可以回答如何在persistence.xml中禁用缓存。

默认情况下禁用二级缓存和查询缓存(查询不会被缓存,除非您明确缓存它们)。一级缓存不能禁用。

我试图通过更改属性来禁用 (...)

这将禁用二级缓存和查询缓存,如果它们已启用。

但它不起作用。

老实说,“它不起作用” 对当前行为与预期行为的描述非常差。提供更多详细信息、(伪)代码、SQL 跟踪可能会有所帮助。

话虽如此,如果问题是关于 HQL,HQL 查询肯定会在后续执行时访问数据库(没有任何查询缓存)。如果需要,请激活 SQL 日志记录以观察这一点。

如果问题是关于Session#get()Session#load(),那么您可以使用Session#refresh() 重新加载实体的状态或调用Session#clear() 以完全清除会话。

【讨论】:

  • 对不起,这没有帮助。
【解决方案2】:

据 hibenrate 团队的一个人说:

二级缓存无所不能 与第一级(会话或 持久性上下文)缓存。这 持久性上下文/会话缓存是 出于各种原因强制。在 事实上,不了解这个关键 部分并在应用程序中忽略它 建筑是灾难的根源。 这里没有快速的解决方案,学习 一些文档。

来源:https://forum.hibernate.org/viewtopic.php?p=2383408
您可以在重试相同查询之前使用 seesion.evict(your object)。

【讨论】:

    【解决方案3】:
    【解决方案4】:

    你可以使用:

    session.setCacheMode(CacheMode.IGNORE)

    在你之后:

    session.createQuery("from Table") 声明。

    这将确保 Hibernate 不会与此查询返回的任何实体的二级缓存交互。

    【讨论】:

      【解决方案5】:

      如果您在单元测试中创建一个新的(不同的)会话,它将“不”使用旧的缓存。或者,如果您先调用 clear()(另一种选择),等等。

      【讨论】:

        【解决方案6】:

        Hibernate有两级Cache,

        1. 会话缓存(一级缓存)是默认缓存,没有禁用机制。

        2. SessionFactory(二级)级缓存:我们必须在 Hibernate cfg 文件中通过 设置 cache_provider。

          我需要从数据库中加载大量数据,我使用了无状态会话,因为有以下功能。

           a. Stateless session does not support session cache and never interact with 
              second level cache.
           b. Stateless session does not support automatic dirty check.
           c. Stateless session does not support cascading to associated entities.
          

          创建无状态会话的语法:

          StatelessSession statelessSession = sessionFactory.openStatelessSession();
          

        【讨论】:

        • entityManager.clear() 不清理所谓的一级缓存吗?
        【解决方案7】:

        第一次查询结果后,调用 session.clear 之后,同样的查询会命中数据库而不是一级缓存

        【讨论】:

          【解决方案8】:

          正如kirill 所指出的,em.clear() 方法实际上可以在某些情况下解决问题(对我有用):

          entityManager.clear();

          【讨论】:

            猜你喜欢
            • 2011-10-13
            • 1970-01-01
            • 2011-03-07
            • 2019-04-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-01-03
            • 2016-08-13
            相关资源
            最近更新 更多