9

I have a Spring Boot application where I want to use Spring Boot cache on a repository method. I have specified @EnableCaching annotation in my Spring Boot app.

When I try to use @Cacheable annotation on my repository method, it throws error:

java.lang.IllegalArgumentException: Cannot find cache named 'cache' for Builder[public abstract java.util.Optional
    myRepoMethod(java.lang.String,java.lang.String)] caches=[cache] |key='' | keyGenerator='' | cacheManager='' | cacheResolver='' |condition='' | unless='' | sync='false' at org.springframework.cache.interceptor.AbstractCacheResolver.resolveCaches(AbstractCacheResolver.java:84)
 at org.springframework.cache.interceptor.CacheAspectSupport.getCaches(CacheAspectSupport.java:224)
 at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.<init>(CacheAspectSupport.java:669)
 at org.springframework.cache.interceptor.CacheAspectSupport.getOperationContext(CacheAspectSupport.java:237)
 at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContexts.<init>(CacheAspectSupport.java:570)
 at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:317)
 at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
 at com.sun.proxy.$Proxy140.findByUserIdAndProduct(Unknown Source) ~[?:?]

I don't know where I have missed out!!

My repository method looks like

    @Cacheable("cache")
    Optional<ModelClass> findByUserIdAndProduct(String userId, String product);

Spring Framework version 5.0.6

aSemy
  • 5,485
  • 2
  • 25
  • 51
Priya
  • 1,096
  • 4
  • 15
  • 32
  • This https://stackoverflow.com/questions/28020245/cannot-find-cache-named-for-cacheableoperation-caches might help you – Alien Aug 27 '18 at 11:07

4 Answers4

10

because you don't add

@Bean
public CacheManager cacheManager() {
    SimpleCacheManager cacheManager = new SimpleCacheManager();
    List<CaffeineCache> caffeineCaches = new ArrayList<>();
    for (CacheConstant cacheType : CacheConstant.values()) {
        caffeineCaches.add(new CaffeineCache(cacheType.toString(),
                Caffeine.newBuilder()
                        .expireAfterWrite(cacheType.getExpires(), TimeUnit.SECONDS)
                        .maximumSize(cacheType.getMaximumSize())
                        .build()));
    }
    cacheManager.setCaches(caffeineCaches);
    return cacheManager;
}
aSemy
  • 5,485
  • 2
  • 25
  • 51
yang wenjie
  • 116
  • 2
  • 4
2

Alternatively, add ehcache.xml:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns='http://www.ehcache.org/v3'>

    <persistence directory="${java.io.tmpdir}" />

    <!-- Default cache template -->
    <cache-template name="default">
        <expiry>
            <tti unit="hours">4</tti>
            <!-- <ttl unit="minutes">2</ttl> -->
        </expiry>
        <listeners>
            <listener>
                <class>com.org.lob.support.LoggingTaskCacheListener</class>
                <event-firing-mode>ASYNCHRONOUS</event-firing-mode>
                <event-ordering-mode>UNORDERED</event-ordering-mode>
                <events-to-fire-on>CREATED</events-to-fire-on>
                <events-to-fire-on>EXPIRED</events-to-fire-on>
                <events-to-fire-on>REMOVED</events-to-fire-on>
                <events-to-fire-on>UPDATED</events-to-fire-on>
            </listener>
        </listeners>
        <resources>
            <heap unit="MB">10</heap>
            <offheap unit="MB">50</offheap>
            <disk persistent="true" unit="GB">1</disk>
        </resources>
        <!-- 
        <heap-store-settings>
            <max-object-graph-size>2000</max-object-graph-size>
            <max-object-size unit="kB">5</max-object-size>
        </heap-store-settings>
        -->
    </cache-template>

    <!-- Cache configurations -->
    <cache alias="books" uses-template="default" >
        <key-type>java.lang.String</key-type>
        <value-type>com.org.lob.project.repository.entity.Book</value-type>     
    </cache>

    <cache alias="files" uses-template="default" >
        <key-type>java.lang.String</key-type>
        <value-type>java.lang.String</value-type>       
    </cache>

</config>

And add the following in application.properties.

# Cache
spring.cache.jcache.config=classpath:ehcache.xml
aSemy
  • 5,485
  • 2
  • 25
  • 51
craftsmannadeem
  • 2,665
  • 26
  • 22
0

In my case, I want to use redis as the backend of cache storage.

I got the same error and resolved with the following config:

application.yml:

spring:
    redis:
        database: 0
        host: localhost
        password:
        port: 6379
    cache:
        type: redis
        redis:
            key-prefix: 'api::'
            # value in milliseconds
            time-to-live: 12000000

Don't forget to put the @EnableCaching annotation with the @SpringBootApplication annotation.

aSemy
  • 5,485
  • 2
  • 25
  • 51
Max Peng
  • 2,879
  • 1
  • 26
  • 43
0

I have the same problem, this is my solution for Spring Boot + EHCache:

File ehcache.xml put in src/main/resources:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="https://www.ehcache.org/ehcache.xsd" 
    updateCheck="true"
    monitoring="autodetect" 
    dynamicConfig="true">

   <diskStore path="/Volumes/Data/CACHE" />

    <defaultCache
        maxElementsInMemory="10000" 
        eternal="true"
        timeToIdleSeconds="120" 
        timeToLiveSeconds="120" 
        overflowToDisk="true"
        maxElementsOnDisk="10000000" 
        diskPersistent="true"
        diskExpiryThreadIntervalSeconds="120" 
        memoryStoreEvictionPolicy="LRU" />
    <!-- IMPORTANT: Change name to your name -->
    <cache 
        name="basicData" 
        maxElementsInMemory="500" 
        eternal="true"
        overflowToDisk="true" 
        timeToIdleSeconds="300" 
        timeToLiveSeconds="600"
        diskPersistent="true" 
        diskExpiryThreadIntervalSeconds="1"
        memoryStoreEvictionPolicy="LFU" />

</ehcache>

Spring Boot Cache Configuration:

@Configuration
@EnableCaching
public class CachingConfig { 
     
    @Bean
    public CacheManager cacheManager() {
        net.sf.ehcache.CacheManager ehCM = ehCacheCacheManager().getObject(); 
        CacheManager cacheManager = new EhCacheCacheManager(ehCM); 
        return cacheManager;
    }

    @Bean
    public EhCacheManagerFactoryBean ehCacheCacheManager() {
        EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean();
        cmfb.setConfigLocation(new ClassPathResource("ehcache.xml"));
        cmfb.setShared(true);

        return cmfb;
    }
}

Java File example:

@Service
@Transactional
public class BasicDataCacheService {

    @Autowired
    private BasicDataDAO basicDataDAO;

    public BasicData getFromDB() {
        BasicData basicData = this.basicDataDAO.getMeta();
        basicData.sort();
        return basicData;
    }

    @CacheEvict(value = "basicData", allEntries = true)
    public void clearCache() {
    }

    @Cacheable("basicData")
    public BasicData getOrFindCache() {
        return getFromDB();
    }
}

And dependencies:

<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId> 
</dependency> 

<dependency>
  <groupId>javax.cache</groupId>
  <artifactId>cache-api</artifactId>
</dependency> 

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId> 
</dependency>
aSemy
  • 5,485
  • 2
  • 25
  • 51
searching9x
  • 1,515
  • 16
  • 16