Description
I'd like to use the Spring Caching abstraction in a way that I can also ask for a bunch of items via a list of provided IDs, and then put the result into the cache, as if I had asked for each item one by one.
As an example, consider the following snippet:
@Cacheable("myCache")
public String findById(String id) {
// ... access DB backend and return item
}
@CollectionCacheable("myCache") // let's suppose this exists and does the magic :D
public Map<String, String> findByIds(Collection<String> ids) {
// ... access DB backend, return map of id to item
}
Then usage would be:
// suppose the following call has happened before the examples below
findById("key1")
// example1: uses "key1" from cache, never calls findByIds
findByIds(Arrays.asList("key1"))
// example2: calls findByIds(["key2"]) and uses value for "key1" from cache,
// puts value for "key2" into cache
findByIds(Arrays.asList("key1", "key2"))
// example3: calls findByIds(["key3", "key4"]) as there's nothing in the cache
// puts value for "key3" and for "key4" separately into cache
findByIds(Arrays.asList("key3", "key4"))
I've implemented this functionality in a proof-of-concept Spring Boot application here: https://github.com/neiser/spring-collection-cacheable The main implementation can be found in CollectionCacheInterceptor#handleCollectionCacheable
The PoC lacks the following:
- Modifying the
BeanFactoryCacheOperationSourceAdvisor
to account for my extraCollectionCacheableCacheAnnotationParser
andCollectionCacheInterceptor
only worked via aBeanFactoryPostProcessor
- No consisderation of
sync
(might be possible, but is harder to implement) - The
CacheAspectSupport
(which I extended inCollectionCacheInterceptor
) has only some methods protected, which required me to copy some of the code fromCacheAspectSupport
inCollectionCacheInterceptor
Still, the tests in MyRepositoryIntTest
show that the PoC works 👍
My questions to you folks are:
- Do you have a better idea how to "modify" the
BeanFactoryCacheOperationSourceAdvisor
in order to support my custom@CollectionCacheable
? - Do you think the annotation
@CollectionCacheable
could be officially integrated in Spring's caching layer (of course with some more polishing)? I've seen some discussions on Stackoverflow and in particular in Insert all elements of a returned list into a Cache [SPR-15213] #19777 but they lack the "partial" invocation feature as in example 2 above (they proposes to use the Cache/CacheManager interfaces to achieve the desired functionality). - If you don't want to integrate something like
@CollectionCacheable
: TheCacheAspectSupport
class is hard to extend for my PoC. The same holds forCollectionCacheableCacheAnnotationParser
, which is extendingSpringCacheAnnotationParser
. Would you mind to make this easier for my use case?
I'm happy to contribute a PR once I know what your opinion on this feature is. I can also polish the PoC further following your recommendations. I appreciate any feedback!