Hibernate二级缓存和Hudson

时间:2013-08-18 09:31:01

标签: java hibernate hudson ehcache second-level-cache

我正在使用带有hibernate的SecondLevelCache。这是我的xml配置文件:

    <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" />

                
                     

我的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>

在我的实体上有一个像这样的注释

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

当我在本地运行我的UnitTest时我没有问题。所有测试都通过了,但如果我在我的Hudson continuos integretion上运行测试,我会遇到以下错误(如果我在@DirtiesContext上设置或不注释,则问题相同):

>     javax.persistence.PersistenceException: org.hibernate.cache.CacheException: java.lang.IllegalStateException:
> The cacheTest Cache is not alive (STATUS_SHUTDOWN)    at
> org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1167)
>   at
> org.hibernate.ejb.AbstractEntityManagerImpl.refresh(AbstractEntityManagerImpl.java:673)
>   at
> org.hibernate.ejb.AbstractEntityManagerImpl.refresh(AbstractEntityManagerImpl.java:641)
> Caused by: org.hibernate.cache.CacheException:
> java.lang.IllegalStateException: The cacheTest Cache is not alive
> (STATUS_SHUTDOWN)     at
> net.sf.ehcache.hibernate.regions.EhcacheTransactionalDataRegion.remove(EhcacheTransactionalDataRegion.java:164)
>   at
> net.sf.ehcache.hibernate.strategy.AbstractEhcacheAccessStrategy.evict(AbstractEhcacheAccessStrategy.java:119)
>   at
> net.sf.ehcache.hibernate.nonstop.NonstopAwareEntityRegionAccessStrategy.evict(NonstopAwareEntityRegionAccessStrategy.java:96)
>   at
> org.hibernate.event.def.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:144)
>   at
> org.hibernate.event.def.DefaultRefreshEventListener.onRefresh(DefaultRefreshEventListener.java:62)
>   at org.hibernate.impl.SessionImpl.fireRefresh(SessionImpl.java:1118)
>   at org.hibernate.impl.SessionImpl.refresh(SessionImpl.java:1098)    at
> org.hibernate.ejb.AbstractEntityManagerImpl.refresh(AbstractEntityManagerImpl.java:666)
> Caused by: java.lang.IllegalStateException: The cacheTest Cache is
> not alive (STATUS_SHUTDOWN)   at
> net.sf.ehcache.Cache$CacheStatus.checkAlive(Cache.java:3946)  at
> net.sf.ehcache.Cache.checkStatus(Cache.java:2664)     at
> net.sf.ehcache.Cache.removeInternal(Cache.java:2288)  at
> net.sf.ehcache.Cache.remove(Cache.java:2207)  at
> net.sf.ehcache.Cache.remove(Cache.java:2125)  at
> net.sf.ehcache.hibernate.regions.EhcacheTransactionalDataRegion.remove(EhcacheTransactionalDataRegion.java:160)

我怎么能解决这个问题? 为什么这只发生在哈德森?


更新

根据@lanimall的建议,我有:

  • 禁用了Hudson上的所有节点;
  • 修改了persistence.xml。

更换

< property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" />

<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory" />

但这并不能解决我的问题(但这是一个很好的开始: - )......错误是一样的)。

我的环境配置是hibernate3和ehcache-2.7.2

3 个答案:

答案 0 :(得分:2)

你正在使用什么版本的hibernate?和Ehcache? 我认为可能发生的事情是hudson正在某些应用程序服务器上运行(例如Glassfish,Tomcat 5,JBoss,Jetty 6等),它可能有一些ehcache或hibernate lib版本与你正在竞争的版本竞争嵌入你的应用程序...因此只有在哈德森运行测试时才会出现问题。一定要仔细研究......

另外,根据ehcache / hibernate文档(http://ehcache.org/documentation/user-guide/hibernate#Configure-Ehcache-as-the-Second-Level-Cache-Provider),请尝试使用“hibernate.cache.region.factory_class”设置而不是“hibernate.cache.provider_class”...

我通常也会使用单件工厂(否则你的JUN​​IT测试将无效......)。基于hibernate版本,使用 hibernate.cache.region.factory_class = net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory

或(对于hibernate 4.x及以上版本)

hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory

希望有所帮助...

答案 1 :(得分:1)

我找到了解决方案!

在我的persistence.xml中,我将2个持久性单元配置为Singleton,并且在某些测试中使用了两者。以这种方式分享EhCacheSingleton。

然后发生当与其中一个关联的EntityFactory关闭时,因此使另一个使用的ehcache关闭(因为在这两个实体管理器之间共享一个Singleton实例)。

非常感谢@lanimall敞开心扉!

答案 2 :(得分:0)

JUnit分享Spring的速度上下文。当我在我的一个测试中明确删除Spring上下文时,我避免了这个异常。