Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
CacheManager abstraction not working well with caches defined as beans [SPR-8081] #12736
I have ehcache caches defined as spring beans:
To make that work, I have the two CacheManagers - the ehcache one, and the new spring one that is part of the cache abstraction:
However, there's a tricky moment - if spring instantiates the EhCacheCacheManager before the caches, then startup fails, because the cacheManager's loadCache() method, that is invoked in afterPropertiesSet(), tries to obtain the caches from the ehcache CacheManager, but they might not be registered with it yet (they get registered whenever they are instantiated as spring beans).
A workarounds I got to use is to set the EhCacheCacheManager depends-on attribute to include all caches - but that's not particularly good - it is likely that someone will forget to add a new cache to the depends-on list, and then he will have hard time finding why his cache is not used.
Btw, the bahaviour is non-deterministic - it works on my local machine, and doesn't work on the server. Perhaps different loading orders.
One solution that comes to my mind is to make the list of caches within the EhCacheCacheManager lazy - i.e. not load it on afterPropertiesSet() (synchornized, double-check locking).
Affects: 3.1 M1
Costin Leau commented
I'm afraid there's not much the Spring container can do. Clearly there's a relationship between your ehcache caches however the container is not aware of it hence the initialization problem. Making EhCacheCacheManager lazy besides the fact that goes against its role (to do eager initialization and validation of the cache), it only postpones the problem since there are no guarantees that the other cache beans would be initialized by the time the cache is accessed.
Bozhidar Bozhanov commented
Hm, what about a ApplicationListener<ContextRefreshedEvent>? Whenever the context is ready, the listener can "grab" the cache manager and call its initialization method. That way it is guarnateed that all cache beans will be in place.
I find this wont-fix a tad annoying. A valid use case is that using Spring 3 method-level
Eyecatcher: java.lang.IllegalArgumentException: loadCaches must not return an empty Collection
Workaround: define a pointlessly disabled cache which will be present when EhCache initialises.
Owen Berry commented
I agree that the won't-fix is a little frustrating, for the same reasons stated previously. I would like to be able to manage my whole ehcache configuration through Spring and properties files, but I have to add a dummy cache in ehcache.xml to get that to work. While experimenting, I subclassed org.springframework.cache.ehcache.EhCacheCacheManager and overrode afterProperties set in the AbstractCacheManager parent class, and with a 1 line change had a working implementation with no dummy cache.
I'm wary of how maintainable this copy-and-paste override is (and the dummy cache really is not that bad), so I'm not going to keep it, but I think it shows how potentially simple the "fix" is. Maybe there's something else I'm not aware of, but it would be nice to know.
Stéphane Nicoll commented
I think you misunderstand what
So if you want to define your