14
votes

I'm trying to replace my old:

@Component
public interface MyEntityRepository extends JpaRepository<MyEntity, Integer> {

    @QueryHints({@QueryHint(name = CACHEABLE, value = "true")})
    MyEntity findByName(String name);
}

by this:

@Component
public interface MyEntityRepository extends JpaRepository<MyEntity, Integer> {

    @Cacheable(value = "entities")
    MyEntity findByName(String name);
}

Because I want to use advanced caching features like no caching of null values, etc.

To do so, I followed Spring tutorial https://spring.io/guides/gs/caching/

If I don't annotate my Application.java, caching simply doesn't work.

But if I add @EnableCaching and a CacheManager bean:

package my.application.config;

@EnableWebMvc
@ComponentScan(basePackages = {"my.application"})
@Configuration
@EnableCaching
public class Application extends WebMvcConfigurerAdapter {

    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("entities");
    }

// ...
}

I get the following error at startup:

java.lang.IllegalStateException: No CacheResolver specified, and no bean of type CacheManager found. Register a CacheManager bean or remove the @EnableCaching annotation from your configuration

I get the same error if I replace My CacheManager bean by a CacheResolver bean like:

@Bean
public CacheResolver cacheResolver() {
    return new SimpleCacheResolver(new ConcurrentMapCacheManager("entities"));
}

Do I miss something ?

2
Implement the CacheConfigurer interface. and implement the methods. A bean of that type is needed to properly configure caching. - M. Deinum
Try to name your cacheManager with the name (entities ) you using in the @cacheable annotation. - herau
@M. Deinum yesterday What is this CacheConfigurer interface ? It's in no documentation. - Pleymor
Yes it is. Check the tip/hint here. - M. Deinum
And are you really following that tutorial or are you "following" that tutorial. You have a web application the tutorial doesn't. The tutorial assumes Spring Boot you aren't... So those are quite different things. - M. Deinum

2 Answers

22
votes

@herau You were right I had to name the bean ! The problem was that there were another bean "cacheManager", so finally, I didn't annotate Application, and created a configuration as:

@EnableCaching
@Configuration
public class CacheConf{
    @Bean(name = "springCM")
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("entities");
    }
}

in MyEntityRepository:

    @Cacheable(value = "entities", cacheManager = "springCM")
    MyEntity findByName(String name);
0
votes

In my case the Spring Boot library was old, and there was no way to easily upgrade it. So I used EHCache 2 version, and it worked in my application. Here is a project I found useful to refer to: https://github.com/TechPrimers/spring-ehcache-example/blob/master/src/main/resources/ehcache.xml