The Scenario
Spring cache abstraction annotation is easy to add cache abilty to the application: Just define CacheManager in confutation, then use annotations: @Cacheable, @CachePut, @CacheEvict to use and maintain the cache.
But what to do if the cache annotation seems doesn't work?
How we know cache doesn't work?
Logging
We can change the log level to print database query in the log. For Cassandra, we can change log level of com.datastax.driver.core.RequestHandler to TRACE.
Debug
We can set a breakpoint at CacheAspectSupport.execute.
If cache works, when we call a method annotated with cache annotation, it will not directly call the method, instead it will be intercepted and hit the breakpoint.
Test
Possible Root Causes
1. The class using cache annotation inited too early
This usually happens when we use @Cache annotated classes in configuration or AOP class.
Spring first creates configuration and AOP class which then cause beans of @Cache annotated classes created before cache config is correctly setup. This makes these beans created without handling @Cache.
Please check Bean X of type Y is not eligible for getting processed by all BeanPostProcessors for detailed explanation
How to troubleshoot
Add a breakpoint at the default constructor of the bean (add one if not exist), then from the stack trace we can figure out why and which bean (or configuration class) causes this bean to be created.
Using @Lazy or ObjectFactory or other approaches to break the eager dependency, restart and check again util the cached method works as expected.
Also check whether there is log like: Bean of type is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2. Calling cached method in same class
Solutions:
- Using self inject or applicationContext.getBean then use the bean to call cached method
- Using @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
Spring cache abstraction annotation is easy to add cache abilty to the application: Just define CacheManager in confutation, then use annotations: @Cacheable, @CachePut, @CacheEvict to use and maintain the cache.
But what to do if the cache annotation seems doesn't work?
How we know cache doesn't work?
Logging
We can change the log level to print database query in the log. For Cassandra, we can change log level of com.datastax.driver.core.RequestHandler to TRACE.
Debug
We can set a breakpoint at CacheAspectSupport.execute.
If cache works, when we call a method annotated with cache annotation, it will not directly call the method, instead it will be intercepted and hit the breakpoint.
Test
Possible Root Causes
1. The class using cache annotation inited too early
This usually happens when we use @Cache annotated classes in configuration or AOP class.
Spring first creates configuration and AOP class which then cause beans of @Cache annotated classes created before cache config is correctly setup. This makes these beans created without handling @Cache.
How to troubleshoot
Add a breakpoint at the default constructor of the bean (add one if not exist), then from the stack trace we can figure out why and which bean (or configuration class) causes this bean to be created.
Using @Lazy or ObjectFactory or other approaches to break the eager dependency, restart and check again util the cached method works as expected.
Also check whether there is log like: Bean of type is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2. Calling cached method in same class
Solutions:
- Using self inject or applicationContext.getBean then use the bean to call cached method
- Using @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)