Hibernate 5.3 with Ehcache 3.5.2 configuration problem


#1

I try to migrate our application from Hibernate 5.2 with Ehcache 2 to Hibernate 5.3 with Jcache and Ehcache 3.

I have a problem to get Hibernate (EntityManagerFactory) started with enabled Jcache/Ehcache in my Tomcat webserver. The problem is: The configuration file ehcache.xml is not found.
I don’t know how to configure the location of this configuration file. Probably it’s a problem with the URI.The result is a (catched) javax.cache.CacheException: org.ehcache.xml.exceptions.XmlConfigurationException: Error parsing XML configuration at file:/META-INF/ehcache.xml in in AbstractRegionFactory.start().

These are my relevant JARs:
cache-api-1.0.0.jar
ehcache-3.5.2.jar
hibernate-commons-annotations-5.0.3.Final.jar
hibernate-core-5.3.0.Final.jar
hibernate-jcache-5.3.0.Final.jar

This is my configuration for the second level cache:
“hibernate.cache.region.factory_class”, “jcache”
“hibernate.javax.cache.provider”, “org.ehcache.jsr107.EhcacheCachingProvider”
“hibernate.javax.cache.uri”, “file:///META-INF/ehcache.xml” // tried many alternative values

The location of my ehcache.xml is
<TOMCAT_HOME>/webapps/myApp/WEB-INF/classes/META-INF/ehcache.xml

What is the correct value of the property “hibernate.javax.cache.uri”?

  • When I put this ehcache.xml in my root directory C: and configure “file:///ehcache.xml”, the configuration file is found and parsed and everything seems to work fine. But that is not the correct location…

Thank you very much in advance!


#2

Sounds like the file was found but it couldn’t be parsed. Try the suggestion in this StackOverflow answer.


#3

Thank you Vlad, but the ehcache.xml is ok.
If I put the ehcache.xml to “C:” (windows) and set property “hibernate.javax.cache.uri” to “file:///ehcache.xml”, it works

Maybe this bug is the problem
https://hibernate.atlassian.net/browse/HHH-12531

So I haven’t found a way to configure a relative path to the ehcache.xml yet.


#4

That might explain why it does not work for you. Most likely, it’s a bug.


#5

This workaround seems to work:

Map<String, String> configuration = new HashMap<>(); 
configuration.put("hibernate.cache.region.factory_class", "jcache");
configuration.put("hibernate.javax.cache.provider", "org.ehcache.jsr107.EhcacheCachingProvider");
URL uRL = getClass().getResource("/META-INF/ehcache.xml");
String ehcache = "file:///" + uRL.getFile();
configuration.put("hibernate.javax.cache.uri", ehcache);

EntityManagerFactory = Persistence.createEntityManagerFactory(persistencemanager, configuration);

If someone has a better idea…


#6

Did you try a classpath:// prefixed URL?

I know there are many libraries out there supporting this.


#7

I tried with “classpath://META-INF/ecache.xml”, in this case the result is a
javax.cache.CacheException: java.net.MalformedURLException: unknown protocol: classpath

The stacktrace is
URI.toURL() line: 1089 [local variables unavailable]
EhcacheCachingProvider$ConfigSupplier.getConfiguration() line: 327
EhcacheCachingProvider.getCacheManager(EhcacheCachingProvider$ConfigSupplier, Properties) line: 127
EhcacheCachingProvider.getCacheManager(URI, ClassLoader, Properties) line: 78
EhcacheCachingProvider.getCacheManager(URI, ClassLoader) line: 186
JCacheRegionFactory.resolveCacheManager(SessionFactoryOptions, Map) line: 143


#8

I wrote a fix for this bug.Just copy to your project file org.hibernate.cache.jcache.internal.JCacheRegionFactory.java and rewrite that method:

@SuppressWarnings("WeakerAccess")
protected CacheManager resolveCacheManager(SessionFactoryOptions settings, Map properties) {
	final Object explicitCacheManager = properties.get( ConfigSettings.CACHE_MANAGER );
	if ( explicitCacheManager != null ) {
		return useExplicitCacheManager( settings, explicitCacheManager );
	}

	final CachingProvider cachingProvider = getCachingProvider( properties );
	final CacheManager cacheManager;
	final URI cacheManagerUri = getUri( properties );
	// ***** begin patch ******
	URI uri = cacheManagerUri;
	URL url = null;
	try {
		uri.toURL();
	} catch (Exception e) {
		try {
			url = getClassLoader(cachingProvider).getResource(cacheManagerUri.toString());
			uri = url.toURI();
		} catch (Exception e1) {
			throw new IllegalArgumentException("Resource not found: " + uri, e1);
		}
	}
	// ****** end patch ******
	if ( cacheManagerUri != null ) {
		cacheManager = cachingProvider.getCacheManager( uri, getClassLoader( cachingProvider ));
	}
	else {
		cacheManager = cachingProvider.getCacheManager();
	}
	return cacheManager;
}

You can now set

<property name="hibernate.javax.cache.uri" value="ehcache.xml"/>

and place ehcache.xml on root of classpath.


#9

Please send a Pull Request to the Hibernate project. Thanks.