Amit Agarwal
Amit Agarwal

Reputation: 77

Spring Cache - @CacheEvict, @CachePut not working while calling from the another method from the same class

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

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

Cached service class:

class testServiceImpl{

@CachePut(key = "#result.id", condition = "#result != null")
public List<String> create(String input) {
......
}

@CacheEvict(key="#id")
public void deleteById(Long id) {
.....
}

public void multiDelete(String input) { 
if(condition...){
  deleteById(2);  //Cache is not Evicted here i.e. the records are still present in getAll call but not in Database.
}else{
  create(input); //New Data is persisted in DB but the same has not been updated in Cache.
}   

@Transactional
@Cacheable
public Map<Long, String> getAll() {
 ...
}

I have tried using the below solutions as well but could not succeed.

//Create a new object of the same class and use the same. In this case, the data is not persisted in DB i.e. it is not deleting the data from DB.
     testServiceImpl testService;
                ...
              public void multiDelete(String input) {   
                if(condition...){
                  testService.deleteById(2);  
                }else{
              testService.create(input); 
            }

Can someone please help me to solve this issue ?

Upvotes: 4

Views: 2680

Answers (1)

cdalxndr
cdalxndr

Reputation: 1541

When you call a method from your service, you are actually calling it through a proxy. The autowired bean is wrapped in a proxy that intercepts the call and handles the cache annotations only for that method.

When you make the call internally, it is made directly on the service object, and without the proxy wrapper, the cache annotation is not processed. See Understanding AOP Proxies

A working alternative is to use AspectJ that will weave the spring aspects that handle cache annotations directly into the code without using any Spring proxies, so you can call internal methods and cache annotation will be handled as expected.

Upvotes: 5

Related Questions