0

I have a service with next methods:

public Optional<Test> getTestWithId100() {
    return get(100);
}

@Cacheable(value = "test", key = "'1'")
public Optional<Test> get(long id) {
    log.error("not from cache");
    return testRepository.findOneById(id);
}

I call method getTestWithId100 from controller, but it only get fresh value.

@Slf4j
@Configuration
@EnableCaching
@AutoConfigureAfter(value = { MetricsConfiguration.class, DatabaseConfiguration.class })
public class CacheConfiguration {

    @PersistenceContext
    private EntityManager entityManager;

    private final MetricRegistry metricRegistry;

    private net.sf.ehcache.CacheManager cacheManager;

    @Inject
    public CacheConfiguration(MetricRegistry metricRegistry) {
        this.metricRegistry = metricRegistry;
    }

    @PreDestroy
    public void destroy() {
        log.info("Remove Cache Manager metrics");
        SortedSet<String> names = metricRegistry.getNames();
        names.forEach(metricRegistry::remove);
        log.info("Closing Cache Manager");
        cacheManager.shutdown();
    }

    @Bean
    public CacheManager cacheManager(Properties properties) {
        log.debug("Starting Ehcache");
        cacheManager = net.sf.ehcache.CacheManager.create();
        cacheManager.getConfiguration().setMaxBytesLocalHeap(properties.getCache().getEhcache().getMaxBytesLocalHeap());
        log.debug("Registering Ehcache Metrics gauges");
        entityManager.getMetamodel().getEntities().forEach(entity -> {
            String name = entity.getName();
            if (name == null || entity.getJavaType() != null)
                name = entity.getJavaType().getName();
            Assert.notNull(name, "entity cannot exist without a identifier");
            net.sf.ehcache.Cache cache = cacheManager.getCache(name);
            if (cache != null)
                cacheManager.replaceCacheWithDecoratedCache(cache, InstrumentedEhcache.instrument(metricRegistry, cache));
        });
        EhCacheCacheManager ehCacheManager = new EhCacheCacheManager();
        ehCacheManager.setCacheManager(cacheManager);
        return ehCacheManager;
    }

}

part of ehcache.xml:

<cache name="test" eternal="true"/>

Why it doesn't work? I tried with different keys but without success.

Boris
  • 4,944
  • 7
  • 36
  • 69
  • 2
    Please see: http://stackoverflow.com/questions/16899604/spring-cache-cacheable-not-working-while-calling-from-another-method-of-the-s – rpozarickij Oct 01 '16 at 10:06

2 Answers2

2

Spring annotations work by proxying / enhancing your classes. The one limitation in this system is when you call a method on the same bean, then that call is not intercepted by the system and thus no annotation based modifications will be applied.

Louis Jacomet
  • 13,661
  • 2
  • 34
  • 43
-1

I think that you are wrong in cache config, let's consider code below (it works fine for me):

@Bean
public CacheManager cacheManager() {
    return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}

@Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
    EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean();
    cmfb.setConfigLocation(new ClassPathResource("ehcache.xml"));
    cmfb.setShared(true);
    return cmfb;
}

And of course, ehcache.xml:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="ehcache.xsd"
    updateCheck="true"
    monitoring="autodetect"
    dynamicConfig="true">

    <diskStore path="java.io.tmpdir" />

    <cache name="movieFindCache"
        maxEntriesLocalHeap="10000"
        maxEntriesLocalDisk="1000"
        eternal="false"
        diskSpoolBufferSizeMB="20"
        timeToIdleSeconds="300" timeToLiveSeconds="600"
        memoryStoreEvictionPolicy="LFU"
        transactionalMode="off">
        <persistence strategy="localTempSwap" />
    </cache>

</ehcache>

This config must help you, if it dosn't solve the problem, notify me. HTH