Issue
I've looked through a lot of similar questions asked here but I'm still not able to find a solution so here's my issue:
I'm trying to setup Ehcache on springboot.
Spring 2.2.6.RELEASE
Ehcache 3.8.1
CacheService
I've got a cache named `myCache`.@Cacheable(value = "myCache")
@GetMapping("/get")
public String get();
CacheConfig
And my config@Configuration
@EnableCaching
public class CacheConfig {
public CacheConfig() {
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder().withCache("myCache",
CacheConfigurationBuilder.newCacheConfigurationBuilder(SimpleKey.class, String.class, ResourcePoolsBuilder.heap(10))).build();
cacheManager.init();
}
}
Error
But I'm getting the following error:java.lang.IllegalArgumentException: Cannot find cache named 'myCache' for Builder...
I managed to get it to work if I put the config in the xml file, but I rather have it in java.
Solution
@Cacheable(value = "myCache")
doesn't create a cache named myCache
in Ehcache. At runtime, if a cache named myCache
is available in Ehcache, it'll use that cache for caching. If not, when attempting to cache at runtime, the exception java.lang.IllegalArgumentException: Cannot find cache named 'myCache'
will be thrown. For @Cacheable(value = "myCache")
to work with Ehcache as the backend, the cache needs to be created somewhere and Spring needs to be made aware of that cache. The simplest way to do that is to include the spring-boot-starter-cache
dependency, add an ehcache.xml
with the Ehcache config to classpath and set the config spring.cache.jcache.config: classpath:ehcache.xml
in application.yml
. You can find a sample application that does that on github
Instead if you do want to configure Ehcache programmatically, you need a org.springframework.cache.CacheManager
bean, to initialize the Ehcache config and link it to Spring. The bean definition could look something like below:
import javax.cache.Caching;
import org.ehcache.config.CacheConfiguration;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.jsr107.Eh107Configuration;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.SimpleKey;
import org.springframework.cache.jcache.JCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager ehCacheManager() {
CacheConfiguration<SimpleKey, String> cacheConfig = CacheConfigurationBuilder
.newCacheConfigurationBuilder(SimpleKey.class, String.class, ResourcePoolsBuilder.heap(10))
.build();
javax.cache.CacheManager cacheManager = Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider")
.getCacheManager();
String cacheName = "myCache";
cacheManager.destroyCache(cacheName);
cacheManager.createCache(cacheName, Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfig));
return new JCacheCacheManager(cacheManager);
}
}
Sample working application that configures Ehcache for Spring through code can be found here on github.
Answered By - devatherock
Answer Checked By - Katrina (JavaFixing Volunteer)