spring-by-pivotal

logo ehcache

Par défaut, la génération des clés  pour le cache ne prend pas en compte les noms des méthodes ni ceux des classes mais uniquement les valeurs des paramètres et cela peut poser de gros problèmes…

Voici un exemple :

@Cacheable(value="sampleCache")
public MyObject method1(String param){
 ...
}

@Cacheable(value="sampleCache")
public MyObject method2(String param){
 ...
}

Si on appelle methode1 avec le paramètre « toto » cela nous retourne un objet A, si on appelle ensuite methode2 avec le paramètre « toto » cela nous retournera l’objet A en cache alors que la methode2 aurait peut être du nous retourner autre chose !!

Pour corriger cela il faut absolument inclure le nom de la classe et de la méthode dans la clé de cache. Voici ma configuration du cache :

@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {
	
	@Bean
	public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
		EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
		ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache-config.xml"));
		return ehCacheManagerFactoryBean;
	}
	
	@Override
	@Bean
	public EhCacheCacheManager cacheManager() {
		EhCacheCacheManager cacheManager = new EhCacheCacheManager();
		cacheManager.setCacheManager(ehCacheManagerFactoryBean().getObject());
		return cacheManager;
	}
	
	@Override
	public KeyGenerator keyGenerator() {
		return new CacheKeyGenerator();
	}
	
	class CacheKeyGenerator implements KeyGenerator {
		
		@Override
		public Object generate(Object target, Method method, Object... params) {
			final List<Object> key = new ArrayList<>();
			key.add(method.getDeclaringClass().getName());
			key.add(method.getName());
			key.add(Objects.hash(params));
			return key;
		}
	}
	
}

A vous de jouer !

Publicités