Configure EHCache with Spring and Hibernate, using multiple cache managers - spring

(first of all, sorry for my english ... I don't speak it very well)
Hi,
I'm developing a multi-module web app using spring framework in version 4.0.9. I have three different jar modules containing three different entity models wired to its own database each other. These three models are using Hibernate in version 4.3.5 and spring too.
I want to configure Ehcache as hibernate's second level cache on each of one jar model modules and likewise I need to configure Ehcache for cache provider at principal webapp project.
model-1.jar (spring + hibernate + ehcache), with hibernate-ehcache dependency version 4.3.5
model-2.jar (spring + hibernate + ehcache), with hibernate-ehcache dependency version 4.3.5
model-3.jar (spring + hibernate + ehcache), with hibernate-ehcache dependency version 4.3.5
webapp.war (spring-mvc + ehcache), with spring-context-support 4.0.9 version dependency
In model-1 module something like this:
(model-1-spring-context.xml)
<bean id="oneSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" lazy-init="true">
<property name="dataSource" ref="oneDataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="net.sf.ehcache.configurationResourceName">one-ehcache.xml</prop>
</props>
</property>
<property name="packagesToScan" value="......" />
</bean>
(one-ehcache.xml)
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd" name="oneHibernateCache">
<diskStore path="/tmp/xxxx"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
model-2 and model-3 with analogous structure to model-1.
And webapp configuration something like this:
(class configuration)
#EnableCaching
#Configuration
public class CacheConfig {
#Bean
public CacheManager cacheManager() {
return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}
#Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
EhCacheManagerFactoryBean factory = new EhCacheManagerFactoryBean();
factory.setConfigLocation(new ClassPathResource("web-ehcache.xml"));
factory.setShared(true);
return factory;
}
}
(web-cache.xml)
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" name="webSpringCache">
<diskStore path="/tmp/zzzzz" />
<defaultCache
maxElementsInMemory="1"
eternal="true"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="1800"
memoryStoreEvictionPolicy="FIFO">
</defaultCache>
I'm having several problems with cache managers, cache names and regions inside them. Spring context doesn't start ok and I don't know how to configure properly the modules.
I'd very pleased if somebody could help me.
Thanks a lot to everybody.

Related

Hibernate 5.3 Spring 5, Ehcache 3.5.2, jdk 10, Hibernate says "Cache provider not started"

...my question is, with this configuration, do i need to "start" ehcache? if yes, how? it is a maze working though the libs dependencies, e.g. need hibernate-ehcache and ehcache? need hibernate-jcache? Here is the final error on tomcat 9 standard out after 3 days of debug:
... 93 common frames omitted
aused by: java.lang.IllegalStateException: Cache provider not started
at org.hibernate.cache.spi.AbstractRegionFactory.verifyStarted(AbstractRegionFactory.java:42)
at org.hibernate.cache.spi.support.RegionFactoryTemplate.buildTimestampsRegion(RegionFactoryTemplate.java:66)
at org.hibernate.cache.internal.EnabledCaching.<init>(EnabledCaching.java:80)
at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:33)
at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:24)
at org.hibernate.service.spi.SessionFactoryServiceInitiator.initiateService(SessionFactoryServiceInitiator.java:
0)
at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.initiateService(SessionFactoryServiceRegistr
Impl.java:68)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263
key config files:
ivy.xml (excerpt):
<dependency org="org.hibernate" name="hibernate-core" rev="5.3.0.Final">
</dependency>
<dependency org="org.hibernate" name="hibernate-jcache" rev="5.3.0.Final" />
<dependency org="org.hibernate" name="hibernate-ehcache"
rev="5.3.0.Final" />
<dependency org="org.springframework.boot" name="spring-boot-starter-cache"
rev="2.0.2.RELEASE" />
<dependency org="org.ehcache" name="ehcache" rev="3.5.2" />
<dependency org="org.springframework" name="spring-orm" rev="5.0.6.RELEASE" />
<dependency org="org.springframework" name="spring-core"
rev="5.0.6.RELEASE" />
Spring hibernateContext.xml (excerpt)
<property name="hibernateProperties">
<props>
<prop key="hibernate.c3p0.acquire_increment">5</prop>
<prop key="hibernate.c3p0.idle_test_period">100</prop>
<prop key="hibernate.c3p0.max_size">20</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.timeout">300</prop>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.use_sql_comments">false</prop>
<!-- <prop key="hibernate.enable_lazy_load_no_trans">true</prop> -->
<!-- ehcache settings -->
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.jcache.JCacheRegionFactory</prop>
<prop key="hibernate.javax.cache.provider">org.ehcache.jsr107.EhcacheCachingProvider</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.default_cache_concurrency_strategy">read-write</prop>
<prop key="hibernate.javax.cache.uri">classpath:jcache.xml</prop>
</props>
</property>
</bean>
jcache.xml (all of it)
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.ehcache.org/v3" xmlns:jsr107="http://www.ehcache.org/v3/jsr107"
xsi:schemaLocation="
http://www.ehcache.org/v3
http://www.ehcache.org/schema/ehcache-core.xsd
http://www.ehcache.org/v3/jsr107
http://www.ehcache.org/schema/ehcache-107-ext.xsd">
<!-- https://hibernate.atlassian.net/browse/HHH-12531 -->
<service>
<jsr107:defaults enable-management="true" enable-statistics="true" default-template="default" />
</service>
<cache alias="org.hibernate.cache.spi.QueryResultsRegion">
<expiry>
<tti unit="seconds">300</tti>
</expiry>
<heap>1024</heap>
</cache>
<cache alias="org.hibernate.cache.spi.TimestampsRegion">
<expiry>
<none />
</expiry>
<heap>4096</heap>
</cache>
<cache-template name="default">
<expiry>
<tti unit="seconds">300</tti>
</expiry>
<heap>1024</heap>
</cache-template>
created a hibernate issue too
https://hibernate.atlassian.net/browse/HHH-12635
I'm not sure creating an issue in Hibernate was a good idea. This is most probably a configuration issue on your side.
The first thing I can say is that hibernate-ehcache should not be there. This is used for Ehcache 2. Not JCache+Ehcache3.
Then, can you please try to rename the jcache.xml to ehcache.xml?
Finally, no, you should not need to start the provided. It should start by itself.
Henri was right that I did not need hibernate-ehcache. But renaming jcache.xml to ehcache.xml was not required.
In short the fix to my error was to add the jcache.xml resource to my ant build, because it was not getting deployed. With that said, for others who may have this error, there is such a maze of possibilities and lack of clear simple-stupid config for hibernate 5.3, spring 5, ehcache 3.5.2, jdk 10, tomcat 9, your only hope (other than dumb luck, which does work) is to put tomcat in debug mode, attach eclipse, add the hibernate-core source to an eclipse project, set a breakpoint in the offending hibernate class/method and see what is not available/expected in your particular configuration.
Also for others trying to make this work, strange, I do need spring-boot-starter-cache, without it none of my spring hibernate config is read. I am a Spring 2.5 guy of 13 years, so i have yet to understand what spring boot is. it is suppose to be an "opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss". but it also seems to be a runtime/embedded tomcat, so whatever, i am sure that it is quite useful sometimes and quite undefined and confusing others....

Lookup jndi resources WebSphere 8.5, Spring 3.1.3, Hibernate 4.1.10 EJB 3

In my application I need to lookup jndi resources for database connection.
I have an EAR which contain my EJB project with remote and stateless ejb: ABean.jar
Reading Using Spring and Hibernate with WebSphere Application Server I defined
in the application.xml of EAR project:
<module>
<ejb>ABean.jar</ejb>
</module>
<resource-ref>
<res-ref-name>jdbc/b</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
In my spring context:
<jee:jndi-lookup
id="aDataSource"
jndi-name="jdbc/b"
cache="true"
expected-type="javax.sql.DataSource"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="META-INF/persistence.xml"/>
<property name="dataSource" ref="aDataSource" />
<property name="persistenceUnitName" value="APU"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.DB2390Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
</bean>
Now, if I install application by WebSphere console, it ask to me to assign the jndi resource to jdbc/b (and it is ok), but if I try to call an ejb, a NameNotFoundException is throw because jdbc/b is not found!
Reading better the previous link i see:
For EJB JAR files, the same resource-ref should be declared in each EJB that needs to access the data source.
so I try to define resource references into my ejb-jar.xml
<enterprise-beans>
<session>
<ejb-name>TestServiceBean</ejb-name>
<ejb-class>it.test.TestServiceBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<resource-ref>
<res-ref-name>jdbc/b</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
</resource-ref>
</session>
</enterprise-beans>
I try to install again (I also assign the jndi resource to jdbc/b) and the call to the ejb run successfully, but if I have n ejb, do I need to assign n-times the same jndi resource to the n ejb resource-ref for jdbc/b?
What is wrong with my configuration? Isn't it possible "point" to the same resource-ref from all ejb? Do you have a complete example?
Per the EE 6 spec, references declared in application.xml must be in the java:app (or java:global) namespaces, and it is recommend that they be in the env subcontext, so:
<res-ref-name>java:app/env/jdbc/b</res-ref-name>
This will allow the resource to be visible to all components in the application. Alternatively, you can declare a reference in the java:module context in ejb-jar.xml or via annotation.
Updated answer. Example based on bkail answer. You need to define resource reference in application.xml like this:
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" version="6">
<display-name>RefTestEAR</display-name>
....
<resource-ref>
<res-ref-name>java:app/env/jdbc/b</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</application>
Then in your application you can access it via:
InitialContext ctx = new InitialContext();
DataSource datasource = (DataSource) ctx.lookup("java:app/env/jdbc/b");
In your case since you are using Spring not InitialContext directly, you will probably need to change the lookup to and also verify if you have datasource reference in persistence.xml (I didn't test that in Spring as I don't have Spring sample at hand):
<jee:jndi-lookup
id="aDataSource"
jndi-name="java:app/env/jdbc/b"
cache="true"
expected-type="javax.sql.DataSource"/>

Ehcache Manager

I have an application that use JDBCTemplate and Hibernate.
Both of this configure to use ehcache but exception thrown:
org.hibernate.cache.CacheException: net.sf.ehcache.CacheException: Another unnamed CacheManager already exists in the same VM. Please provide unique names for each CacheManager in the config or do one of following:
JDBCTemplate configured using spring xml
Hibernate configured using hibernate.cfg.xml
Please help.
I tried to disable the default cache in ehcache.xml but failed and i have the shared property set to true which also caused fail.
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">
<diskStore path="java.io.tmpdir" />
<!--<defaultCache eternal="true" maxElementsInMemory="50000"
overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
timeToLiveSeconds="0" memoryStoreEvictionPolicy="LRU"
/>
-->
<cache name="genericDao" eternal="false" maxElementsInMemory="50000"
overflowToDisk="false" memoryStoreEvictionPolicy="LFU" />
<cache name="reportDao" eternal="false" maxElementsInMemory="50000"
timeToIdleSeconds="28800" timeToLiveSeconds="28800"
overflowToDisk="false" memoryStoreEvictionPolicy="LFU" />
</ehcache>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="WEB-INF/ehcache/ehcache.xml"></property>
<property name="shared" value="true"></property>
</bean>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache"></property>
</bean>
How to provide unique name in this case ?
Thanks.
Create two ehcache.xml configuration with different names.

Spring Entitymanager java.lang.ClassFormatError

This is 2nd day that I am struggling with this issue.
We have a web app that uses spring and hibernate. Now We are trying to expose some functionality to command line. So We should be able to run a class from command line(without web app) so it should have access to spring and hibernate.
<context:annotation-config/>
<context:component-scan base-package="com.x.y.z"/>
<jpa:repositories base-package="com.x.y" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="jpaProperties">
<props>
<prop key="javax.persistence.validation.mode">NONE</prop>
<prop key="hibernate.validator.apply_to_ddl">false</prop>
<prop key="hibernate.validator.autoregister_listeners">false</prop>
<prop key="hibernate.format_sql">false</prop>
</props>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="database" value="SQL_SERVER" />
<property name="showSql" value="false" />
</bean>
</property>
</bean>
Here I am using LocalEntityManagerFactoryBean but it seems there is no way to set datasource to it. It gets from persistance.xml
If I use LocalContainerEntityManagerFactoryBean I can set datasource(it has datasource property)
persistance.xml:
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="oms-jpa">
<class>com.domain.User</class>
</persistence-unit>
In persistance.xml I am not defining any database informaton for datasource, so LocalEntityManagerFactoryBean does not work for this.
what I am getting:
Error creating bean with name 'entityManagerFactory' defined in file [C:\Users\ekamoliddinov\IdeaProjects\web\conf\spring-config.xml]: Invocation of init method failed; nested exception is java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/validation/Validation
googled then some says:
Jar versions messed up
jee-api.jar is missing
But I have jee-api.jar.
My questions:
What is causing the above exception?
Can I use LocalContainerEntityManagerFactoryBean without having web
container? Spec does not say anything about this.
If i can not use LocalContainerEntityManagerFactoryBean then how can I set up
LocalEntityManagerFactoryBean so it should use my datasource not from
persistance.xml(I can not define anything in persistance.xml).
I am using spring version 3.1.3 with hibernate 4.1.8.Final and i am in command line(I do no have jee environment)
Sorry about more than one questions, but all questions are arising from the same root I think.
Any help will be appreciated.
Thanks.
After trying 3 days I fixed the issue. The jars where messed up :)
It was because I have jee-api.jar in my classpath and I was running the code from command line, I had not web env. So there was not any impl of jee-api.jar in my env. That is why it was giving the above exception. I removed jee-api.jar and disappeared.
Another thing That I can tell: we can use LocalContainerEntityManagerFactoryBean from command line. I am using it.
The last thing: We can not set datasource to LocalEntityManagerFactoryBean
This my help to someone.

Another unnamed CacheManager already exists in the same VM (ehCache 2.5)

This is what happens when I run my junit tests...
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 ]
What's the reason behind the exception. Could there be more than 1 cacheManager running simultaneously?
This is how I configured the cachManager using Sping 3.1.1. It sets explicitly the scope of the cacheManager to "singleton"
<ehcache:annotation-driven />
<bean
id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
scope="singleton"
/>
The ehcache.xml looks like
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false"
maxBytesLocalHeap="100M"
name="cacheManager"
>
....
</ehcache>
Finally my class
#Component
public class BookingCache implements CacheWrapper<String, BookingUIBean> {
#Autowired
private CacheManager ehCacheManager;
....
}
I'm very sure that I'm dealing with only one cacheManager in my code base. Something else is probably running the n-th instance.
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"/>
I had the same issue with my integration tests using JPA (2.0) + Hibernate (3.6.4) + Spring (3.2.4).
The issue was resolved using following Hibernate configuration:
<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory"/>
instead of using
<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.EhCacheRegionFactory"/>
Your problem is the context loading optimization built in the Spring test framework. Spring (per default) does not destroy the context once the test class is done, in hope that another test class might reuse it (instead of creating it from scratch).
You can override this default using #DirtiesContext, or if you use maven you can set surefire forkMode to "always" and create a new VM per test class.
After upgrading to Hibernate 5 I had to use:
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"/>
instead of:
<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory"/>
Please note that the packages differ from each other.
You may also try to set name"xxx" on your ehcache.xml configuration (on the ehcache element).
That did the trick for me, as I think I had another cache configuration lurking in one of the modules of my app.
The shared solution also works, but I don't know the far-ranging implications of that.
http://forums.terracotta.org/forums/posts/list/6495.page
https://norrisshelton.wordpress.com/2012/03/08/spring-3-1-caching-abstraction-with-ehcache/
For posterity: A better way is to use the "accept-existing" property of the EhCacheManagerFactoryBean.
Setting the EhCacheManagerFactoryBean#shared to true worked for me.
Setting the EhCacheManagerFactoryBean#acceptExisting to true DIDN'T work for me.
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;
}
}
As explained in Using EhCache in Spring 4 without XML
if you just test your business service,not second level cache,you can remove second level configuration in your spring config file,your test will be run successfully. there is my second level configuration :
<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>
if i change to full configuration of second level cache config ,the real webapp use in running time,like this:
<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>
then i get the same Exception "Another unnamed CacheManager already exists in the same VM"
In my case, we have a custom cache manager defined as bean.
Also a custom application context so we don't use the spring junit runner... hence the #DirtiesContext doesn't work.
The trick is to retrieve the cache instance from the bean, on that cache get the cacheManager (the instance from EHCache). and on that cachemanager call the removeCache method.
Put this in a method annotated with #After and your cache is removed from the VM after each test. Like this:
#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;
}
I solved it by adding following to resources.groovy :
beans = {
...
aclCacheManager(EhCacheManagerFactoryBean) {
shared = true
}
...
}
It happened to me when switching to Spring Boot 2.0.2. Resolved it by doing the following:
REMOVE in application.yml
spring.jpa.properties.hibernate.cache.region.factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
REMOVE in pom.xml
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
KEEP in pom.xml only
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
</dependency>
For future readers, the cause of this problem in my case was that in my pom.xml file I had imported the hibernate-ehcache library, which unknown to me also already contained the ehcache library, and then explicitly imported the net.sf.ehache libray.
This seemed to work fine when I was running as a standalone app (a command line utility for example) but it caused the error in the original post when running on a tomcat server.
Changing my pom file from:
<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>
To:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.0.2.Final</version>
</dependency>
<!-- ehcache dependency removed -->
Fixed the problem. If anyone has any idea why the problem only appeared when running in a tomcat container I'd be interested to know..
In glassfish 3.0.1, I traced the issue to IniShiroFilter getting initialize twice, which happens when concurrent requests are fired just after the server start. Following is a stack trace from two different threads corresponding to two HTTP requets:
[#|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)
Another thread
[#|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)
Looking at the stack trace ApplicationFilterConfig.java:248 could be the culprit. Or, glassfish is initializing filters in the wrong context, for comparison, Tomcat initializes filters during BootStrap.
In my case Problem is component-scan and java config.
root-context.xml
<context:component-scan base-package="org.beansugar">
servlet-context.xml
<context:component-scan base-package="org.beansugar">
spring component-scan work two times on xml files.
it generate beans inside SpringConfig.java each run time.
then duplicate cache manager was created.
so, I changed that like below.
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>
This error also happens with wrong mapping files. The message is horrible, doesn't say the cause.
In my case configuration was as follows:
<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>
Changing the EHCache provider class did the job for me. I was using cache provider class as org.hibernate.cache.EhCacheProvider instead i changed this to:
net.sf.ehcache.hibernate.SingletonEhCacheProvider
As of Spring Boot 2.1.2 the following configuration worked to resolve the issue. (Note, these are snippets of the overall config.)
Dependencies:
<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 config:
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 configuration:
<?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>
The application I am working on slows down drastically without a working cache. So, to validate I simply ran the application and hit one of the read intense endpoints.
In my case the Manager was created by this bean (ehCache 2.10):
<bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="shared" value="false"/>
</bean>
the only solution that worked for me is to destroy it manually in that way :
#Inject
private EhCacheManagerFactoryBean ehCacheManagerFactoryBean;
And then
ehCacheManagerFactoryBean.destroy();

Resources