15

I have been working with Spring Cache Abstraction and Ehcache. I'm using the @Cacheable annotation on a target method like so:

@Component
public class DataService {
    @Cacheable(value="movieFindCache", key="#name")
    public String findByDirector(String name) {
        return "hello";
    }
}

This is my jUnit test:

public class ServiceTest extends AbstractJUnit4SpringContextTests{

    @Resource
    private DataService dataService;

    @Test
    public void test_service() {
        System.err.println(dataService.findByDirector("Hello"));
    }
}

This is not working fine when I debug with jUnit test. It throws an IllegalArgumentException as follows:

java.lang.IllegalArgumentException: Null key returned for cache operation (maybe you are using named params on classes without debug info?) CacheableOperation[public java.lang.String com.eliteams.quick4j.web.service.ExcelDataService.getCarData()] caches=[movieFindCache] | key='#name' | condition='' | unless=''
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.cache.interceptor.CacheAspectSupport.generateKey(CacheAspectSupport.java:315)
at org.springframework.cache.interceptor.CacheAspectSupport.collectPutRequests(CacheAspectSupport.java:265)

I have the following config:

applicationContext.xml:

<cache:annotation-driven cache-manager="cacheManager"/>
<bean id="ehCacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
      p:configLocation="classpath:ehcache.xml" p:shared="true"/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
      p:cacheManager-ref="ehCacheManagerFactory"/>

ehcache.xml:

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

<diskStore path="java.io.tmpdir" />

<cache name="movieFindCache"
       maxEntriesLocalHeap="10000"
       maxEntriesLocalDisk="1000"
       eternal="false"
       diskSpoolBufferSizeMB="20"
       timeToIdleSeconds="300" timeToLiveSeconds="600"
       memoryStoreEvictionPolicy="LFU"
       transactionalMode="off">
    <persistence strategy="localTempSwap" />
</cache>

note: If I don't specify the "key" in the @Cacheable annotations, it works.

Is there anything I forgot to specify? config? annotations?

Javasick
  • 2,753
  • 1
  • 23
  • 35
Green Lei
  • 3,150
  • 2
  • 20
  • 25

4 Answers4

15

Had the same problem, root cause was that in tests parameter was really null, so, just added not null check

@Cacheable(value="movieFindCache", key="#p0", condition="#p0!=null")
public String findByDirector(String name) {...}
Javasick
  • 2,753
  • 1
  • 23
  • 35
13

you could try to replace key with #p0

@Component
public class DataService {
    @Cacheable(value="movieFindCache", key="#p0")
    public String findByDirector(String name) {
        return "hello";
    }
}

reference from Spring Cache Abstraction VS interfaces VS key param ("Null key returned for cache operation" error)

david chi
  • 176
  • 1
  • 6
3

I had this happen using ehCache 3. It worked fine in my local environment using the parameter name as the key, for instance:

// this would fail
@Cacheable(value="movieFindCache", key="name")
    public String findByDirector(String name) {

but when deployed in a test environment I would receive the error. I resolved this by removing the key property from the @Cacheable annotation for methods with a single parameter:

// this worked
@Cacheable("movieFindCache")
    public String findByDirector(String name) {
Wil
  • 556
  • 6
  • 12
-3

The message of the IllegalArgumentException is pretty explicit. The following table in the spring documentation indicates what is available for using argument names.

And the relevant javac options are documented. You want the -g ones in this context.

Louis Jacomet
  • 13,661
  • 2
  • 34
  • 43