Skip to content

Spring caching: combining multiple @Cacheable within @Caching annotation doesn't work [SPR-11124] #15750

@spring-projects-issues

Description

@spring-projects-issues

Pieter Van der Meeren opened SPR-11124 and commented

When combining multiple @Cacheable annotations within a @Caching annotation, the caching does not work due to bug in CacheAspectSupport class.

Consider the following service method, annotated with the Spring caching annotationa:

public class DummyServiceImpl implements DummyService {
	private static final List<String> BIG_LIST = asList("four", "five", "six", "seven", "eight", "nine");
	private static final List<String> SMALL_LIST = asList("one", "two", "three");

	private static final Logger LOGGER = Logger.getLogger(DummyServiceImpl.class);

	public static final Long SMALL_CACHE_KEY = 1L;
	public static final Long BIG_CACHE_KEY = 2L;


	@Override
	@Caching(cacheable = { @Cacheable(value = "bigCache", unless = "#result.size() < 4"), 
							@Cacheable(value = "smallCache", unless = "#result.size() > 3") })
	public List<String> getTheList(Long id) {
		LOGGER.info("Cache NOT hit, executing service logic...");
		if (SMALL_CACHE_KEY.equals(id)) {
			return SMALL_LIST;
		} else if (BIG_CACHE_KEY.equals(id)) {
			return BIG_LIST;
		} else {
			return emptyList();
		}
	}
}

You can see we are combining two @Cacheable annotations, we define a cache "smallCache" which will hold the result if the size of the result is < 4 elements (we do this using the "unless" parameter).Then we define another cache "bigCache" which will hold the result if the size of the result is > 3.

If we call the cached service method with a key which should returen the small list, we see that the smallCache size is incremented (cache size is now = 1).But if we call the cached service method again with the same key we still see the service logic is executed instead of returning the cached value.

After some investigation, I think the problem resides in the CacheAspectSupport class, in the method inspectCacheables, the local variable updateRequired is overwritten if there is more then 1 cache defined, which makes that the cached value is never reused if you have more then 1 @Cacheable annotation within a @Caching enclosing annotation.

Small maven project attached to reproduce the issue (testclass: DummyServiceImplTest).


Affects: 3.2.4, 3.2.5

Attachments:

Issue Links:

Referenced from: commits 73a8a1b, b0b40da

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions