javahibernatejunitehcachehibernate-cache

Hibernate Second Level Cache & JUnit


I'm trying to use SecondLevelCache with hibernate. This is my xml configuration file:

    <persistence-unit name="EntityTestHibernate" transaction-type="RESOURCE_LOCAL">
        <properties>
            <property name="hibernate.show_sql" value="false"/>
            <property name="hibernate.format_sql" value="false"/>
            <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/DB_NAME"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
            <property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
            <property name="hibernate.connection.username" value="USERNAME"/>
            <property name="hibernate.connection.password" value="PASSWORD"/>            
            <property name="hibernate.cache.use_second_level_cache" value="true"/>             
            <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" /> 
            <property name="hibernate.cache.provider_configuration_file_resource_path" value="/test/ehcache.xml" />     
        </properties>
    </persistence-unit>

My ehcache.xml:

<ehcache name="cacheTest" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <defaultCache eternal="true" maxElementsInMemory="100" overflowToDisk="false" />
    <cache  name="entityCache" 
            maxEntriesLocalHeap="50"
            eternal="false"
            timeToLiveSeconds="120"         
    />
</ehcache>

and on my entity there is an annotation like this

@Cache(region="entityCache", usage=CacheConcurrencyStrategy.READ_WRITE )

When i run a UnitTest i have following error (problem is same if i set or not annotation on it @DirtiesContext):

net.sf.ehcache.CacheException: Another CacheManager with same name 'cacheTest' already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.
The source of the existing CacheManager is: DefaultConfigurationSource [ ehcache.xml or ehcache-failsafe.xml ]
    at net.sf.ehcache.CacheManager.assertNoCacheManagerExistsWithSameName(CacheManager.java:573)
    at net.sf.ehcache.CacheManager.init(CacheManager.java:389)
    at net.sf.ehcache.CacheManager.<init>(CacheManager.java:371)
    at net.sf.ehcache.hibernate.EhCacheProvider.start(EhCacheProvider.java:93)
    at org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge.start(RegionFactoryCacheProviderBridge.java:72)
    at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:238)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1872)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:850)
    at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:56)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)

I just have configured my CacheManager with hibernate xml file and i don't know how to manage that error. I read somewhere that i must use a RegionFactory but in ehcache documentation it's not a best practise. How could i solve my problem in right way?


Solution

  • not sure where you saw that using RegionFactory is not a best practice...check out ehcache documentation at http://ehcache.org/documentation/user-guide/hibernate#Configure-Ehcache-as-the-Second-Level-Cache-Provider...and that's exactly what they say you should be using.

    Also, You should use the SingletonEhCacheRegionFactory which should fix your junit issue (singleton means there will be 1 cache manger only...hence no 2 cachemanager with same cachename as shown in your exception)

    net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory

    Please note: For Hibernate 4, use org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory instead of net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory

    Hope that helps.