net.sf.ehcache.ObjectExistsException: 默认缓存已配置

net.sf.ehcache.ObjectExistsException: The Default Cache has already been configured

我正在使用 Spring (4.2.6.RELEASE) 和 Hibernate(5.1.0.Final)。在 spring.xml.
中定义为 bean 的 Hibernate 属性 我为二级缓存库添加了 ehcache。 我收到错误 net.sf.ehcache.ObjectExistsException:默认缓存已在以下项目中配置
有没有人可以帮忙?

***************************** applicationContext-dao.xml ********* ******************************

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="databaseProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="file:///C:/Config/database.properties"/>
    </bean>


    <bean id="transactionDatasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="${db.url}"/>
        <property name="username" value="${db.username}"/>
        <property name="password" value="${db.password}"/>
    </bean>

    <!-- Hibernate 4 SessionFactory Bean definition -->
    <bean id="hibernate4AnnotatedSessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="transactionDatasource" />
        <property name="annotatedClasses">
            <list>
                <value>com.company.model.db.ApplicationStatEntity</value>
                <value>com.company.DeviceCapEntity</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.current_session_context_class">thread</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.jdbc.batch_size">50</prop>
                <prop key="hibernate.connection.url">jdbc:oracle:thin:@<IP>:1522/rac2</prop>
                <prop key="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</prop>

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

            </props>
        </property>
    </bean>

</beans>

我按照 GenericDao Class 实现了。 class 将实体作为通用实体。

***************************** GenericDao *************** *******

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;
import org.hibernate.*;
import org.hibernate.hql.internal.ast.QuerySyntaxException;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Iterator;
import java.util.List;



public class GenericDaoImpl<GenericEntity> implements GenericDao<GenericEntity> {

    private Class<GenericEntity> type;
    private ClassPathXmlApplicationContext context = null;
    protected SessionFactory sessionFactory = null;
    Logger log = Logger.getLogger(GenericDaoImpl.class.getName());

    public GenericDaoImpl() {
        context = getApplicationContext();
        sessionFactory = getSessionFactory();
    }

    private ClassPathXmlApplicationContext getApplicationContext() {
        if (this.context == null) {
            this.context = new ClassPathXmlApplicationContext("applicationContext-dao.xml");
        }
        return this.context;
    }

    private SessionFactory getSessionFactory() {
        if(this.sessionFactory==null) {
            this.sessionFactory = (SessionFactory) getApplicationContext().getBean("hibernate4AnnotatedSessionFactory");
        }
        return this.sessionFactory;
    }

    public Class<GenericEntity> getMyType() {
        return this.type;
    }

    public void setType(Class<GenericEntity> type) {
        this.type = type;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }


    public void insert(GenericEntity genericEntity) throws DaoException {
        Session session = this.sessionFactory.openSession();
        Transaction transaction = null;
        try {
            transaction = session.beginTransaction();
            log.info("[GeneicDaoImpl.insert]  hibernate session opened");
            session.save(genericEntity);
            log.info("[GeneicDaoImpl.insert]  insertion done");
            transaction.commit();
        } catch (QuerySyntaxException e) {
            if (transaction != null) {
                transaction.rollback();
                log.error(
                        "[GeneicDaoImpl.insert]  An error occured ID generation with table mapping. "
                        + "Check schema,table name in entity object or check table in database",
                        e);
                throw new DaoException("[GeneicDaoImpl.insert]  hibernate error occured,rollback done. Stack Trace : /n" + e.getStackTrace());
            }
        } catch (AnnotationException e) {
            if (transaction != null) {
                transaction.rollback();
                log.error("[GeneicDaoImpl.insert]  An error occured ID generation with sequence. Check sequence name in entity object and in database",
                          e);
                throw new DaoException("[GeneicDaoImpl.insert]  hibernate error occured,rollback done. Stack Trace : /n" + e.getStackTrace());
            }
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
                log.error("[GeneicDaoImpl.insert]  hibernate error occured,rollback done", e);
                throw new DaoException("[GeneicDaoImpl.insert]  hibernate error occured,rollback done. Stack Trace : /n" + e.getStackTrace());
            }

        } finally {
            session.close();
        }
    }
}

而在 Junit 测试 Class 中,我这样调用插入批处理。

************************** TestClass.java ************** ***************

    public class TestClass {

        @Test
        public void insertTest() {
            GenericDao<ApplicationStatEntity> insertBatchDao = new GenericDaoImpl();
            ApplicationStatEntity applicationStatEntity = new ApplicationStatEntity();
            applicationStatEntity.setId(102);
            applicationStatEntity.setDeviceid("SamsungShitty");
            try {
                insertBatchDao.insert(applicationStatEntity);
            } catch (DaoException e) {
                e.printStackTrace();
            }
        }
    }

****************************** ehcache.xml *********** ***********

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>

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

    <defaultCache maxEntriesLocalHeap="10000" eternal="false"
                  timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30"
                  maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120"
                  memoryStoreEvictionPolicy="LRU" statistics="true">
        <persistence strategy="localTempSwap" />
    </defaultCache>


</ehcache>

使用缓存标签而不是 defaultCache。

ehcache.xml 可以是

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <diskStore path="java.io.tmpdir/ehcache" />

    <defaultCache maxEntriesLocalHeap="10000" eternal="false"
                  timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30"
                  maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120"
                  memoryStoreEvictionPolicy="LRU" statistics="true">
        <persistence strategy="localTempSwap"/>
    </defaultCache>



    <cache name="sampleCache" 
        maxEntriesLocalHeap="10000" 
        eternal="false"
        timeToIdleSeconds="120" 
        timeToLiveSeconds="120" 
        diskSpoolBufferSizeMB="30"
        maxEntriesLocalDisk="10000000" 
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU" 
        statistics="true">
        <persistence strategy="localTempSwap" />
    </cache>

</ehcache>

来自 ehcache 文档

<!--

Default Cache configuration. These settings will be applied to caches
created programmatically using CacheManager.add(String cacheName).
This element is optional, and using CacheManager.add(String cacheName) when
its not present will throw CacheException

The defaultCache has an implicit name "default" which is a reserved cache name.

-->

<defaultCache maxEntriesLocalHeap="0" eternal="false" timeToIdleSeconds="1200" timeToLiveSeconds="1200">
    <terracotta/>
</defaultCache>