77

这就是我运行 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 ]

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

这就是我使用 Sping 3.1.1 配置 cachManager 的方式。它明确地将 cacheManager 的范围设置为“singleton”

<ehcache:annotation-driven />

<bean
    id="cacheManager"
    class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
    scope="singleton"
    />

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>

最后我的课

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

     @Autowired
     private CacheManager ehCacheManager;
      ....
}

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

4

18 回答 18

46

Your EhCacheManagerFactoryBean may be a singleton, but it's building multiple CacheManagers and trying to give them the same name. That violates Ehcache 2.5 semantics.

Versions of Ehcache before version 2.5 allowed any number of CacheManagers with the same name (same configuration resource) to exist in a JVM.

Ehcache 2.5 and higher does not allow multiple CacheManagers with the same name to exist in the same JVM. CacheManager() constructors creating non-Singleton CacheManagers can violate this rule

Tell the factory bean to created a shared instance of the CacheManager in the JVM by setting the shared property to true.

<bean id="cacheManager"
      class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
      p:shared="true"/>
于 2012-06-02T17:07:07.817 回答
44

我在使用 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"/>

而不是使用

<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.EhCacheRegionFactory"/>
于 2014-01-30T14:06:57.773 回答
23

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

你可以使用@DirtiesContext 覆盖这个默认值,或者如果你使用maven,你可以将surefire forkMode 设置为“always”并为每个测试类创建一个新的VM。

于 2012-08-14T15:29:48.480 回答
13

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

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

代替:

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

请注意,这些软件包彼此不同。

于 2017-01-03T21:58:22.747 回答
12

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

这对我有用,因为我认为我的应用程序的一个模块中潜伏着另一个缓存配置。

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

于 2012-08-24T16:35:24.953 回答
6

对于后代:更好的方法是使用EhCacheManagerFactoryBean的“接受现有”属性。

于 2016-02-05T05:29:38.717 回答
2

在我的例子中,我们有一个定义为 bean 的自定义缓存管理器。也是一个自定义应用程序上下文,所以我们不使用 spring junit runner ...因此 @DirtiesContext 不起作用。

诀窍是从 bean 中检索缓存实例,在该缓存上获取 cacheManager(来自 EHCache 的实例)。并在该缓存管理器上调用 removeCache 方法。

将其放入使用 @After 注释的方法中,每次测试后您的缓存都会从 VM 中删除。像这样:

@After
public void destroy() {
    MyCustomCacheManager customCacheManager = (MyCustomCacheManager) context.getBean("yourCustomCacheManagerBean");

    try {
        net.sf.ehcache.Cache cache = customCacheManager.getCache();
        net.sf.ehcache.CacheManager cacheManager = cache.getCacheManager();
        cacheManager.removeCache("nameOfYourCache");
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }

    context.destroy();
    context = null;
}
于 2014-10-31T07:39:26.023 回答
2

如果您只是测试您的业务服务,而不是二级缓存,您可以在 spring 配置文件中删除二级配置,您的测试将成功运行。有我的二级配置:

 <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="persistenceUnitName" value="defaultPU" />
        <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">false</prop>
                <!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
                <prop key="hibernate.cache.use_second_level_cache">false</prop>
                <prop key="hibernate.cache.use_query_cache">false</prop>
            </props>
        </property>
    </bean>

如果我更改为二级缓存配置的完整配置,则真正的 webapp 在运行时使用,如下所示:

    <bean id="entityManagerFactory"
            class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="persistenceUnitName" value="defaultPU" />
            <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
            <property name="jpaProperties">
                <props>
                    <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                    <prop key="hibernate.show_sql">false</prop>
                    <!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
                    <prop key="hibernate.cache.use_second_level_cache">true</prop>
                    <prop key="hibernate.cache.use_query_cache">true</prop>
                    <prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>               
                    <prop key="net.sf.ehcache.configurationResourceName">ehcache/ehcache-hibernate-local.xml</prop>
                </props>
            </property>
        </bean>

然后我得到相同的异常“另一个未命名的 CacheManager 已存在于同一 VM 中”

于 2013-09-30T06:48:23.767 回答
2

切换到Spring Boot 2.0.2时发生在我身上。通过执行以下操作解决了它:

在 application.yml 中删除

spring.jpa.properties.hibernate.cache.region.factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory

在 pom.xml 中删除

<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
</dependency>

仅保留在 pom.xml 中

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
</dependency>
于 2018-05-14T08:16:43.047 回答
2

设置EhCacheManagerFactoryBean#sharedtrue对我有用。

设置为EhCacheManagerFactoryBean#acceptExistingtrue我不起作用。

import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

@Configuration
public class EhCacheConfiguration {

    @Bean
    public EhCacheCacheManager ehCacheCacheManager() {

        return new EhCacheCacheManager(ehCacheManagerFactoryBean().getObject());
    }


    @Bean
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {

        EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean();

        cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
        cacheManagerFactoryBean.setShared(true);

        return cacheManagerFactoryBean;
    }
}

正如在没有 XML 的 Spring 4 中使用 EhCache 中所解释的那样

于 2018-10-20T10:55:34.687 回答
2

我通过将以下内容添加到 resources.groovy 来解决它:

beans = { ... aclCacheManager(EhCacheManagerFactoryBean) { shared = true } ... }

于 2015-10-03T11:24:35.133 回答
1

对于未来的读者,这个问题的原因是在我的 pom.xml 文件中我导入了 hibernate-ehcache 库,我不知道它也已经包含了 ehcache 库,然后显式导入了 net.sf.ehache图书馆。

当我作为独立应用程序(例如命令行实用程序)运行时,这似乎工作正常,但在 tomcat 服务器上运行时导致原始帖子中的错误。

从以下位置更改我的 pom 文件:

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-ehcache</artifactId>
            <version>5.0.2.Final</version>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.7.4</version>
        </dependency>

至:

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-ehcache</artifactId>
            <version>5.0.2.Final</version>
        </dependency>
        <!-- ehcache dependency removed -->

修复了问题。如果有人知道为什么只有在 tomcat 容器中运行时才会出现问题,我很想知道..

于 2016-02-11T13:37:23.750 回答
0

在 glassfish 3.0.1 中,我将问题追溯到 IniShiroFilter 两次初始化,这发生在服务器启动后触发并发请求时。以下是对应于两个 HTTP 请求的两个不同线程的堆栈跟踪:

[#|2012-11-28T08:25:10.630-0800|SEVERE|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=28;_ThreadName=Thread-1;|java.lang.Exception: Stack trace
        at java.lang.Thread.dumpStack(Thread.java:1249)
        at org.apache.shiro.web.servlet.IniShiroFilter.<init>(IniShiroFilter.java:124)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:303)
        at com.sun.enterprise.web.WebContainer.createFilterInstance(WebContainer.java:725)
        at com.sun.enterprise.web.WebModule.createFilterInstance(WebModule.java:1948)
        at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:248)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
        at com.sentilla.filter.DumpFilter.doFilter(DumpFilter.java:152)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:277)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
        at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
        at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:322)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:239)
        at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
        at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
        at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
        at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
        at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
        at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
        at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
        at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
        at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
        at java.lang.Thread.run(Thread.java:662)

另一个线程

[#|2012-11-28T08:25:15.299-0800|SEVERE|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=29;_ThreadName=Thread-1;|java.lang.Exception: Stack trace
        at java.lang.Thread.dumpStack(Thread.java:1249)
        at org.apache.shiro.web.servlet.IniShiroFilter.<init>(IniShiroFilter.java:124)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:303)
        at com.sun.enterprise.web.WebContainer.createFilterInstance(WebContainer.java:725)
        at com.sun.enterprise.web.WebModule.createFilterInstance(WebModule.java:1948)
        at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:248)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
        at com.sentilla.filter.DumpFilter.doFilter(DumpFilter.java:152)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:277)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
        at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
        at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:322)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:239)
        at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
        at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
        at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
        at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
        at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
        at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
        at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
        at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
        at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
        at java.lang.Thread.run(Thread.java:662)

查看堆栈跟踪 ApplicationFilterConfig.java:248 可能是罪魁祸首。或者,glassfish 在错误的上下文中初始化过滤器,为了比较,Tomcat 在 BootStrap 期间初始化过滤器。

于 2012-11-20T00:42:25.423 回答
0

在我的情况下,问题是组件扫描和 java 配置。

root-context.xml
<context:component-scan base-package="org.beansugar">

servlet-context.xml
<context:component-scan base-package="org.beansugar">

spring component-scan 对 xml 文件工作两次。它每次运行时都会在 SpringConfig.java 中生成 bean。然后创建了重复的缓存管理器。

所以,我改变了如下。

root-context.xml
<context:component-scan base-package="org.beansugar">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

servlet-context.xml
<context:component-scan base-package="org.beansugar" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
于 2014-08-27T05:11:34.580 回答
0

错误的映射文件也会发生此错误。消息很可怕,没有说明原因。

于 2016-02-16T12:26:34.620 回答
0

Spring Boot 2.1.2开始,以下配置可以解决该问题。(注意,这些是整体配置的片段。)

依赖项:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>5.2.8.Final</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-ehcache</artifactId>
  <version>5.2.8.Final</version>
</dependency>

application.yml 配置:

spring:
  jpa:
    open-in-view: false
    hibernate:
      ddl-auto: none
    show-sql: true
    properties:
      dialect: org.hibernate.dialect.MySQLDialect
      net:
        sf:
          ehcache:
            configurationResourceName: ehcache.xml
      hibernate:
        cache:
          use_second_level_cache: true
          region:
            factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory

ehcache.xml 配置:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
  <!-- Required elements -->
  <diskStore path="java.io.tmpdir"/>
  <defaultCache
    maxElementsInMemory="10000"
    eternal="false"
    timeToIdleSeconds="120"
    timeToLiveSeconds="120"
    overflowToDisk="true"/>

  <!-- Cache settings per class -->
  <cache name="com.mystuff.component.services.example.Book"
    maxElementsInMemory="1000"
    eternal="false"
    timeToIdleSeconds="300"
    timeToLiveSeconds="600"
    overflowToDisk="true"/>
</ehcache>

我正在处理的应用程序在没有工作缓存的情况下会急剧变慢。因此,为了验证,我只是运行了应用程序并点击了读取密集的端点之一。

于 2019-02-09T14:51:05.810 回答
0

在我的例子中,Manager 是由这个 bean 创建的(ehCache 2.10):

  <bean id="ehcache"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="shared" value="false"/>
  </bean>

对我有用的唯一解决方案是以这种方式手动销毁它:

@Inject
private EhCacheManagerFactoryBean ehCacheManagerFactoryBean;

接着

ehCacheManagerFactoryBean.destroy();
于 2021-03-02T01:00:06.350 回答
0

在我的情况下,配置如下:

<spring.boot.version>1.5.8.RELEASE</spring.boot.version>
<spring.boot.yarn.version>2.4.0.RELEASE</spring.boot.yarn.version>
<spring.version>4.3.7.RELEASE</spring.version>

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>3.5.1-Final</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-ehcache</artifactId>
  <version>3.5.1-Final</version>
</dependency>

更改 EHCache 提供程序类为我完成了这项工作。我使用的是缓存提供程序类,因为org.hibernate.cache.EhCacheProvider我将其更改为: net.sf.ehcache.hibernate.SingletonEhCacheProvider

于 2018-11-13T08:55:15.477 回答