Bala Bala - 1 month ago 66
Java Question

Spring Cache @Cacheable - not working while calling from another method of the same bean

Spring cache is not working when calling cached method from another method of the same bean.

Here is an example to explain my problem in clear way.

Configuration:

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

<bean id="myCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="myCache" />
</bean>

<!-- Ehcache library setup -->
<bean id="myCache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:shared="true">
<property name="configLocation" value="classpath:ehcache.xml"></property>
</bean>

<cache name="employeeData" maxElementsInMemory="100"/>


Cached service :

@Named("aService")
public class AService {

@Cacheable("employeeData")
public List<EmployeeData> getEmployeeData(Date date){
..println("Cache is not being used");
...
}

public List<EmployeeEnrichedData> getEmployeeEnrichedData(Date date){
List<EmployeeData> employeeData = getEmployeeData(date);
...
}

}


Result :

aService.getEmployeeData(someDate);
output: Cache is not being used
aService.getEmployeeData(someDate);
output:
aService.getEmployeeEnrichedData(someDate);
output: Cache is not being used


The
getEmployeeData
method call uses cache
employeeData
in the second call as expected. But when the
getEmployeeData
method is called within the
AService
class (in
getEmployeeEnrichedData
), Cache is not being used.

Is this how spring cache works or am i missing something ?

Answer

I believe this is how it works. From what I remember reading, there is a proxy class generated that intercepts all requests and responds with the cached value, but 'internal' calls within the same class will not get the cached value.

From https://code.google.com/p/ehcache-spring-annotations/wiki/UsingCacheable

Only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual cache interception at runtime even if the invoked method is marked with @Cacheable.

Comments