另一个未命名的CacheManager已经存在于同一个VM中(ehCache 2.5)

sim*_*mou 73 junit spring ehcache

这是我运行junit测试时会发生的事情......

Another CacheManager with same name 'cacheManager' 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 ]
Run Code Online (Sandbox Code Playgroud)

异常背后的原因是什么?可以同时运行多个cacheManager吗?

这就是我使用Sping 3.1.1配置cachManager的方法.它将cacheManager的范围明确设置为"singleton"

<ehcache:annotation-driven />

<bean
    id="cacheManager"
    class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
    scope="singleton"
    />
Run Code Online (Sandbox Code Playgroud)

ehcache.xml看起来像

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
     updateCheck="false"
     maxBytesLocalHeap="100M" 
     name="cacheManager"
     >
 ....
 </ehcache>
Run Code Online (Sandbox Code Playgroud)

最后我的课

@Component
public class BookingCache implements CacheWrapper<String, BookingUIBean> {

     @Autowired
     private CacheManager ehCacheManager;
      ....
}
Run Code Online (Sandbox Code Playgroud)

我非常确定我在代码库中只处理一个cacheManager.其他东西可能正在运行第n个实例.

Eme*_*gia 45

您的EhCacheManagerFactoryBean可能是单例,但它正在构建多个CacheManagers并尝试为它们指定相同的名称.这违反了Ehcache 2.5 语义.

版本2.5之前的Ehcache版本允许在JVM中存在任意数量的具有相同名称(相同配置资源)的CacheManager.

Ehcache 2.5及更高版本不允许在同一JVM中存在多个具有相同名称的CacheManager.创建非Singleton CacheManagers的CacheManager()构造函数可能违反此规则

通过将shared属性设置为true,告诉工厂bean在JVM中创建CacheManager的共享实例.

<bean id="cacheManager"
      class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
      p:shared="true"/>
Run Code Online (Sandbox Code Playgroud)

  • 有一点需要注意,如果Spring自动执行EhCacheManagerFatoryBean,即使将p:shared设置为true,您仍可能会收到错误.解决这个问题的方法不是使用文件的默认名称,而是使用ehcache.xml重命名文件,并使用新文件名将p:config-location添加到EhCacheManagerFactoryBean声明中. (5认同)
  • 如果我错了,请纠正我,但这是不是意味着第二次测试将重新使​​用第一次测试中的缓存,其中还有任何缓存数据?这可能导致难以调试行为,因为第二个测试不是以众所周知的状态开始的.然后,测试结果可能取决于测试顺序.(当然,黑盒测试不应该取决于是否使用了缓存,但是依赖于缓存状态的性能测试或者您正在测试自己的缓存工具是否完全有效,该缓存工具使用ehcache.) (3认同)

Fel*_*ers 40

我使用JPA(2.0)+ Hibernate(3.6.4)+ Spring(3.2.4)进行集成测试时遇到了同样的问题.使用以下Hibernate配置解决了该问题:

<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory"/>
Run Code Online (Sandbox Code Playgroud)

而不是使用

<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.EhCacheRegionFactory"/>
Run Code Online (Sandbox Code Playgroud)

  • 我修改了这个解决方案来修复我的Spring Boot测试问题:我使用[org.hibernate.cache.ehcache.EhCacheRegionFactory而不是net.sf.ehcache.hibernate.EhCacheRegionFactory用于Hibernate 4](http://www.ehcache.org/文档/ 2.8 /集成/ hibernate.html#可选).使用Spring Boot,你可以在application.properties中设置它:spring.jpa.properties.hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory或者使用@TestPropertySource,如果你想将配置限制为测试. (3认同)

小智 21

您的问题是Spring测试框架中构建的上下文加载优化.Spring(默认情况下)在测试类完成后不会破坏上下文,希望另一个测试类可以重用它(而不是从头开始创建它).

您可以使用@DirtiesContext覆盖此默认值,或者如果您使用maven,则可以将surefire forkMode设置为"always"并为每个测试类创建一个新VM.

  • 这可以在不改变实际运行时配置的情况下彻底解决测试环境中的问题.太好了! (3认同)
  • forkmode =总是很好的喊叫但是已被弃用.请参阅:http://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html TRY forkCount = 1(默认值),reuseForks = false (2认同)

小智 12

您也可以尝试在ehcache.xml配置(在ehcache元素上)设置名称"xxx".

这对我来说很有把握,因为我认为我的应用程序的一个模块中潜伏着另一个缓存配置.

共享解决方案也有效,但我不知道其中的广泛影响.


小智 9

升级到Hibernate 5后我不得不使用:

<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"/>
Run Code Online (Sandbox Code Playgroud)

代替:

<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory"/>
Run Code Online (Sandbox Code Playgroud)

请不要另外的包裹.


Nis*_*ith 6

对于后代:更好的方法是使用EhCacheManagerFactoryBean的"accept-existing"属性.