没有 ehcache.xml 的 Hibernate 二级缓存

Hibernate 2nd level cache without ehcache.xml

我正在尝试将 Ehcache 配置为休眠二级缓存,到目前为止,我找到的所有示例都指导您在类路径中创建一个 ehcache.xml 文件,例如:

<ehcache updateCheck="false">

    <diskStore path="java.io.tmpdir" />

    <defaultCache maxElementsInMemory="10000" eternal="false"
        statistics="true" timeToIdleSeconds="120" timeToLiveSeconds="120"
        overflowToDisk="true" diskPersistent="false" 
        diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />

    <cache name="com.yourcompany.CachedEntity" eternal="true" maxElementsInMemory="1000" />     

</ehcache>

然后如下配置Hibernate:

<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"/>
<property name="net.sf.ehcache.configurationResourceName" value="/ehcache.xml" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cache.use_second_level_cache" value="true" />

在我的工作场所,我们鼓励尽可能使用 java 配置并避免使用 XML 配置文件。对于如何实现这一点,我将不胜感激。

Whosebug 问题 using ehcache in spring 4 without xml mentioned by learningJava 展示了如何在 java 中配置 ehcache CacheManager 但你仍然需要一种方法来告诉休眠它应该使用你配置的 java CacheManager.

一种可能的方法是通过 hibernate.cache.region.factory_class 属性 配置自定义 ehcache 区域工厂。如果您查看 SingletonEhCacheRegionFactory 的实现,您会发现用您自己的 CacheManager.

进行交换将非常容易

我怀疑缓存的 java 配置和 xml 配置之间的映射非常简单,但是如果 ehcache 在解析缓存时在幕后执行一些 'magic stuff' xml 配置,让 java 配置正确的工作可能有点棘手。

我也找不到这个问题的示例代码,所以我想我会分享我的解决方案。 @Pieter 的回答让我走上了正确的轨道,您需要实现自己的 EhCacheRegionFactory class 以便您可以提供自定义 java 配置对象。看来股票库只支持xml。这是我的解决方案:

public class CustomEhCacheRegionFactory extends EhCacheRegionFactory{

  private static final EhCacheMessageLogger LOG = Logger.getMessageLogger(
        EhCacheMessageLogger.class,
        CustomCacheRegionFactory.class.getName()
  );

  @Override
  public void start(Settings settings, Properties properties) throws CacheException {
    this.settings = settings;
    if ( manager != null ) {
        LOG.attemptToRestartAlreadyStartedEhCacheProvider();
        return;
    }

    try {

        final Configuration configuration = new Configuration();
        configuration.addCache( getEntityCacheConfiguration() );

        manager = new CacheManager( configuration );
        mbeanRegistrationHelper.registerMBean( manager, properties );
    }
    catch (net.sf.ehcache.CacheException e) {
        //handle
    }
  }

  /**
   * Create the basic second level cache configuration
   * @return
   */
  private CacheConfiguration getEntityCacheConfiguration()
  {
    CacheConfiguration config = new CacheConfiguration("entity", 50000);
    config.setTimeToIdleSeconds(86400);
    config.setTimeToLiveSeconds(86400);

    return config;
  }
}