1

My Cache annotation registering, which is being shown in the TRACE log:

2019-11-04 23:55:52,229 TRACE AnnotationCacheOperationSource:102 - **Adding cacheable method 'getMaximumSimilarItems'** with attribute: [Builder[public java.lang.Integer com.quote.manager.impl.SystemConfigManagerImpl.getMaximumSimilarItems()] caches=[attachments] | key='#root.methodName' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false']
@Cacheable(value = "attachments", key = "#root.methodName")
    public Integer getMaximumSimilarItems() {

        logger.info("GetMax");
        SystemConfig systemConfig = systemConfigDao.getSystemConfig();

        Integer maxSimilarItems = systemConfig.getMaximumSimilarItems();

        if(maxSimilarItems != null) {
            return maxSimilarItems;
        }

        return 20;
    }

Also when debugging, stack trace

I see the cache interceptor on the stack for the call and after the call. But still, nothing is cached. I tried multiple cache implementations.

Any ideas on where to set any debug points in Spring's cache implementation to figure out why it's not caching?

I tried XML config and Java Config @EnableCaching.

<bean id="cacheManager" class="org.springframework.cache.jcache.JCacheCacheManager">
        <property name="cacheManager">
        <bean class="org.springframework.cache.jcache.JCacheManagerFactoryBean" 
            p:cacheManagerUri="classpath:ehcache.xml" />
        </property>
    </bean> 

<cache:annotation-driven  cache-manager="cacheManager" />


2019-11-05 11:16:51,370  INFO Eh107CacheManager:378 - Registering Ehcache MBean javax.cache:type=CacheStatistics,CacheManager=file./home/work/workspace-quotes/.metadata/.plugins/org.eclipse.wst.server.core/tmp7/wtpwebapps/app/WEB-INF/classes/ehcache.xml,Cache=attachments
2019-11-05 11:16:51,756  INFO Eh107CacheManager:378 - Registering Ehcache MBean javax.cache:type=CacheStatistics,CacheManager=file./home/work/workspace-quotes/.metadata/.plugins/org.eclipse.wst.server.core/tmp7/wtpwebapps/app/WEB-INF/classes/ehcache.xml,Cache=attachments

I see the caches defined in ehCache.xml are registering when the app starts up as well, so the cache is being started.

<ehcache:config
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:ehcache='http://www.ehcache.org/v3'
  xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.1.xsd">

  <ehcache:cache alias="attachments">

    <ehcache:resources>
      <ehcache:heap unit="entries">100</ehcache:heap>
      <ehcache:offheap unit="MB">1</ehcache:offheap>
    </ehcache:resources>
  </ehcache:cache>
</ehcache:config>
otterslide
  • 550
  • 6
  • 14
  • have you enabled caching? Add @EnableCaching to Main application class. Also, what is methodName here? – Vinay Prajapati Nov 05 '19 at 05:07
  • I just updated the question, I pasted my config. root.methodName should be the name of the method, but I also tried without any key, and with a dummy parameter without keys, and it still doesn't work. According to this doc https://docs.spring.io/spring/docs/3.2.0.RC1/reference/html/cache.html #root.methodName should be the name of the method being called. – otterslide Nov 05 '19 at 16:23
  • Is there some invalid expression I can put into @Cacheable to make it throw an error, just to make sure it is being processed? – otterslide Nov 05 '19 at 16:57
  • Are you calling `getMaximumSimilarItems` method from the another class? [link](https://stackoverflow.com/questions/16899604/spring-cache-cacheable-not-working-while-calling-from-another-method-of-the-s) – MartinBG Nov 05 '19 at 17:53
  • @MartinBG Yes I am calling from another class. I have found the problem. The method is being called inside a @ Service in a method marked with @ PostConstruct . If I wait for everything to initialize and then call the same code that calls the method, then it's working. It looks like all @ Autowires have to finish and only then @ Cacheable is available? I need to somehow call some initialize code before the MVC/Tomcat becomes available, and that code should have @ Cacheable working. Any ideas how to do this? – otterslide Nov 05 '19 at 18:38
  • I called the code after the Root context is initialized and it's all working as expected now. – otterslide Nov 05 '19 at 19:22

1 Answers1

0

So the problem was that I was calling the @Cacheable function too early, before the context was initialized. Once I called it after, it's working fine.

I added:

 implements Runnable, ApplicationListener<ContextRefreshedEvent>  {

and

@Override
public void onApplicationEvent(ContextRefreshedEvent arg0) {

String name = arg0.getApplicationContext().getDisplayName();

if (name.contains("Root")) {
    // ANY CODE That requires @Cacheable is called HERE!.. 
    // Will not work if ran before this, such as inside @PostConstruct

    }
}

The "Root" check is kind of a hack to only call when the Root event is done, otherwise it gets called twice. I don't know how else to differentiate between the events.

otterslide
  • 550
  • 6
  • 14