Search code examples
javaspring-bootcachingehcache

Spring Boot Caching with EhCache doesn't work


I'm using EhCache and Spring Boot to cache the HTTP response from the external API, but the cache doesn't seem to work.

I'm adding Thread.sleep (2000); to simulate the delay that should be skipped when using a cached response. But it is not, and with each method call, a delay and an external API are also called.

Here is my cache configuration class

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {

    private static final String TRANSPORT_LOCATIONS = "transportLocations";
    private static final int TTL_MILLISECONDS = 15;

    @Bean
    public net.sf.ehcache.CacheManager ehCacheManager() {
        CacheConfiguration transportLocationCache = new CacheConfiguration();
        transportLocationCache.setName(TRANSPORT_LOCATIONS);
        transportLocationCache.setMaxEntriesLocalHeap(1000);
        transportLocationCache.setMemoryStoreEvictionPolicy("LRU");
        transportLocationCache.setTimeToLiveSeconds(TTL_MILLISECONDS);

        net.sf.ehcache.config.Configuration config = new net.sf.ehcache.config.Configuration();
        config.addCache(transportLocationCache);
        return net.sf.ehcache.CacheManager.newInstance(config);
    }

    @Bean
    @Override
    public CacheManager cacheManager() {
        return new EhCacheCacheManager(ehCacheManager());
    }
}

And method, which should be cached

    @Cacheable(value = TRANSPORT_LOCATIONS, cacheManager = "cacheManager")
    public HttpResponse<String> sendTransportLocationsPostRequest(
            final LinkedHashMap<String, Object> bodyStructure,
            final String url)
            throws Exception {
        Thread.sleep(2000);
        final String body = buildBody(bodyStructure);
        final HttpRequest request = buildPostRequest(url, body);

        return client.send(request, HttpResponse.BodyHandlers.ofString());
    }

Do you have any idea, why this is not working?

Thanks for your advices.


Solution

  • When key is not specified in the Cacheable annotation, then all the method parameters are considered as a key which is happening here.

    Refer - https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/cache/annotation/Cacheable.html

    key - Default is "", meaning all method parameters are considered as a key, unless a custom keyGenerator() has been configured.

    Since you only need single key in the TRANSPORT_LOCATIONS cache, you can specify method name as the key

    @Cacheable(value = TRANSPORT_LOCATIONS, cacheManager = "cacheManager", key = "#root.methodName")