Enterprise Java

Setting TTL for @Cacheable – Spring

Today I was asked to set the expiry time of cache for some of the keys our application is using, so I quickly started looking for all of the options provided by Spring @Cacheable notation to set up the expiry time or time to live. Since Spring does not provide any configurable option to achieve it, I build one implementation leveraging @Scheduled annotation with a fixed delay, as follows:

@CacheEvict(allEntries = true, cacheNames = { "EMPLOYEE_", "MANAGER_" })
@Scheduled(fixedDelay = 30000)
public void cacheEvict() {
}

Now the problem is I want cache names as well as the fixed delay time period should be populated from environmental values instead of hard coded values. To achieve the same I declared variables(populated from properties file) at class level and populated the values of the key in the annotation which made IDE to complain that values must be constant, as follows:

“The value for annotation attribute CacheEvict.cacheNames must be a constant expression”

Then I started looking for other options to get the values for the keys from environment and came across fixedDelayString element of @Scheduled notation which helped me to achieve my goal, as follows:

@Scheduled(fixedDelayString = "${couchbase.cache.flush.fixed.delay}")
public void cacheEvict() {
}

Looking for the similar element for @CacheEvict annotation as well, which is unfortunately not available given me a hint after reading the the comment on a bug SPR-10778 which says:

“The cache abstraction supports the CacheResolver abstraction now and it can be specified globally, per class and/or on a specific operation. The CacheResolver give you the ability to compute the caches to use in code so you have all the flexibility that you want.”

As bug says to make use of CacheResolver to dynamically populate the cache names, I used AbstractCacheResolver implementation of it to get the names of cache from environment, as follows:

@Value("#{'${couchbase.cache.flush}'}")
private String couchbaseCacheFlush;

@Bean(name = "customCacheResolver")
	public CacheResolver cacheResolver() {
		CacheResolver cacheResolver = new AbstractCacheResolver(cacheManager()) {
			@Override
			protected Collection<String> getCacheNames(
					CacheOperationInvocationContext<?> context) {
				return Arrays.asList(couchbaseCacheFlush.split(","));
			}
		};
		return cacheResolver;
	}

Modifying the cacheEvict() to use custom cache resolver instead of cache names completed my task for the day, as follows:

@CacheEvict(allEntries = true, cacheResolver = "customCacheResolver")
@Scheduled(fixedDelayString = "${couchbase.cache.flush.fixed.delay}")
public void cacheEvict() {
}

Complete source is available on github.

Reference: Setting TTL for @Cacheable – Spring from our JCG partner Arpit Aggarwal at the Arpit Aggarwal blog.

Arpit Aggarwal

Arpit is a Consultant at Xebia India. He has been designing and building J2EE applications since more than 6 years. He is fond of Object Oriented and lover of Functional programming. You can read more of his writings at aggarwalarpit.wordpress.com
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Aakanksha Jain
Aakanksha Jain
5 years ago

Hi Arpit,
I have a doubt
Does the whole cache gets flushed after the expiry time is reached? or flushing happens key wise?

Arpit Aggarwal
5 years ago
Reply to  Aakanksha Jain

The code will flush the values of the keys specified and not the entire cache.

Coder
Coder
4 years ago

The title should have been how to ‘purge the cache’. TTL is misleading here

Back to top button