I have a simple spring boot with redis application that i am building to cache master data of 3 entities emails, products and countries. i have used the spring boot starter dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
also i am using started configuration in my application.properties file
spring.cache.type=redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.cache.redis.key-prefix=masterDataApp
spring.cache.redis.use-key-prefix=true
The cacheable methods are
@Service
public class MasterDataService {
@Cacheable(value="EMAILS")
public List<Email> getEmails() {
System.out.println(" Loading Data from getEmails");
return emails;
}
@Cacheable(value="PRODUCTS")
public List<Product> getProducts() {
System.out.println(" Loading Data from getProducts");
return products;
}
@Cacheable(value="COUNTRIES")
public List<Country> getCountries() {
System.out.println(" Loading Data from getCountries");
return countries;
}
}
The issue is once i load one of the methods from this class, the other 2 methods return the same data as the first method even though they return different Lists and have different Values Cacheable annotation. What am i doing wrong?
The solution is to have a keygeneratory. and add it to the annotation of the method.
This helps in segregating the caches
@Cacheable(value="PRODUCTS", keyGenerator = "customKeyGenerator")
public List<Product> getProducts() {
System.out.println(" Loading Data from getProducts");
return products;
}
@Cacheable(value="COUNTRIES", keyGenerator = "customKeyGenerator")
public List<Country> getCountries() {
System.out.println(" Loading Data from getCountries");
return countries;
}
@Bean("customKeyGenerator")
public KeyGenerator keyGenerator() {
return new CustomKeyGenerator();
}
public class CustomKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params) {
String key = target.getClass().getSimpleName() + "_"
+ method.getName() + "_"
+ StringUtils.arrayToDelimitedString(params, "_");
System.out.println(key);
return key;
}
}
But the question still remains what is the value of value in the annotation as it does nothing to segregate the caches