rohanagarwal rohanagarwal - 4 years ago 129
Java Question

Spring cacheable annotation doesn't work before deployment completes

I have the following classes and interfaces(simplified to make things clear).

@Serivce
class Service1 {

@Cacheable("cacheName")
public Metadata preLoadMetadata() {
// load data from database
}
}

@Service
class Service2 implements Loader {

@Autowired @Lazy
private Service1 service1;

@Overrride
public CacheWrapper getCacheWrapper() {
return new CacheWrapper(() -> service1.preLoadMetadata());
}
}

interface Loader {
CacheWrapper getCacheWrapper();
}

class CacheWrapper {

private Callable callable;

public CacheWrapper(Callable callable) {
this.callable = callable;
}

public getCallable() {
return callable;
}
}


The Spring bean responsible for loading the cache at the time of deployment.

@Component
class LoadCache {

@Autowired
private List<Loader> allLoaders;

@PostConstruct
public void load() {
allLoaders.getCacheWrapper().getCallable().call();
}
}


preLoadMetadata()
doesn't save the data in the cache but it does execute. After deployment is complete and I call the same method
preLoadMetadata()
again, then it saves the data in the cache.

Why does
@Cacheable
doesn't work at the time of deployment?

If I manually use
put
method of
Cache
to populate cache inside method annotated with
@PostConstruct
, I am able to do it successfully while deployment.

I am using Tomcat as server.

I am using Couchbase cache behind Spring cache abstraction.

Answer Source

The root cause for not working of Cacheable annotation: afterSingletonsInstantiated() method sets the initialized flag to true only when BeanFactory has instantiated all the beans. If the initialized flag is false, no caching operations are performed. Here, inside the post construct, when we start pre-loading caches, then it is highly probable that LoadCache is not the last bean to be instantiated. Hence, no caching operations are performed(while using caching annotations).

Hence, EventListener annotation responding to ContextRefreshEvent is the best thing to use in this case which ensures that the context has started and then only loading of caches take place.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download