【问题标题】:Enable Ehcache for all entities为所有实体启用 Ehcache
【发布时间】:2015-09-17 09:31:54
【问题描述】:

我在 Wildfly 8.2 上使用 Spring Data JPA、Hibernate 4.3.10.Final、Ehcache。我想测试应用服务器如何处理缓存中的所有数据。

问题是:是否可以默认为所有扫描的实体启用二级缓存?

实际上,我想避免在每个实体上添加@Cache(因为该项目有 100 多个)。

JPA 属性

... data source definition ...
<property name="sharedCacheMode" value="ALL" />

休眠属性

<prop key="hibernate.generate_statistics">true</prop>

<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="net.sf.ehcache.configurationResourceName">/ehcache.xml</prop>

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="true"
         monitoring="autodetect"
         dynamicConfig="true">
    <diskStore path="java.io.tmpdir/ehcache" />

    <defaultCache maxElementsInMemory="1000000000"
                  eternal="true"
                  overflowToDisk="false"
                  diskPersistent="false"
                  diskExpiryThreadIntervalSeconds="120"
                  memoryStoreEvictionPolicy="LRU"
                  statistics="true"
                  >
    </defaultCache>
    <!-- 
    <cache name="org.hibernate.cache.internal.StandardQueryCache"
            eternal="false"
            timeToLiveSeconds="120">
            <persistence strategy="localTempSwap"/>
    </cache> -->
</ehcache>

编辑: 按照 Dragan Bozanovic 的建议尝试了 &lt;prop key="javax.persistence.sharedCache.mode"&gt;ALL&lt;/prop&gt;,但它不影响该过程。

这是 SELECT e FROM MyEntity e 执行 2 次的统计日志:

17:00:00,597 | INFO  | StatisticalLoggingSessionE:275  |  | Session Metrics {
    71157 nanoseconds spent acquiring 1 JDBC connections;
    0 nanoseconds spent releasing 0 JDBC connections;
    145393 nanoseconds spent preparing 1 JDBC statements;
    386233 nanoseconds spent executing 1 JDBC statements;
    0 nanoseconds spent executing 0 JDBC batches;
    822075 nanoseconds spent performing 41 L2C puts;
    0 nanoseconds spent performing 0 L2C hits;
    0 nanoseconds spent performing 0 L2C misses;
    0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
    0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
}
17:00:00,597 | INFO  | StatisticalLoggingSessionE:275  |  | Session Metrics {
    63973 nanoseconds spent acquiring 1 JDBC connections;
    0 nanoseconds spent releasing 0 JDBC connections;
    127262 nanoseconds spent preparing 1 JDBC statements;
    282918 nanoseconds spent executing 1 JDBC statements;
    0 nanoseconds spent executing 0 JDBC batches;
    452598 nanoseconds spent performing 41 L2C puts;
    0 nanoseconds spent performing 0 L2C hits;
    0 nanoseconds spent performing 0 L2C misses;
    0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
    0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
}

返回了 41 行,这是正确的。但是我看到41 L2C puts 2 次,不应该是41 L2C puts 然后是41 L2C hits 吗?

【问题讨论】:

  • 配置似乎生效了 - 您正在将实体存储到 L2 缓存中。关于统计信息,请尝试按 id(entityManager.find(MyEntity.class, id),或 Spring Data 中的等效项)读取实体。这里你正在执行查询,Hibernate 必须在数据库中执行它。
  • .setHint("org.hibernate.cacheable", true) 一起使用效果更好 :)。感谢您的帮助!
  • 您是否将该提示添加到查询中?如果是这样,您真的希望查询可缓存吗?既然您已将 use_query_cache 设置为 false,为什么它会起作用?
  • 是的,我做到了。为此,我将use_query_cache 切换为true。我不想让所有查询都可缓存,而是在缓存中加载所有实体以查看内存使用情况。

标签: spring hibernate ehcache


【解决方案1】:

是的,如here 所述,添加到您的persistence.xml

<shared-cache-mode>ALL</shared-cache-mode>

如果您不通过persistence.xml 配置Hibernate,请在javax.persistence.sharedCache.mode 配置属性中设置所需的值。

但是,您可能希望通过以下方式实现相同的效果:

<shared-cache-mode>DISABLE_SELECTIVE</shared-cache-mode>

这样,如果您以后决定为某些实体关闭缓存,您可以使用 @Cacheable(false) 注释它们。

【讨论】:

  • 实际上,我没有persistence.xml,因为我已经在使用 Spring 进行配置/扫描。这就是我用&lt;property name="sharedCacheMode" value="ALL" /&gt; 替换&lt;shared-cache-mode&gt;ALL&lt;/shared-cache-mode&gt; 的原因。我目前正在尝试.findAll() 实体并在完成后检查缓存以查看它是否有效。感谢DISABLE_SELECTIVE 提示!
  • 好的,在这种情况下,您可能需要使用 javax.persistence.sharedCache.mode 配置属性。我也在我编辑的答案中提到了它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-06
  • 1970-01-01
  • 2019-09-27
  • 2023-03-29
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多