Spring缓存 - 缓存操作返回了空键

15

我一直在使用Spring Cache Abstraction和 Ehcache。我正在使用@Cacheable 注解来标注一个目标方法,如下所示:

我一直在使用Spring Cache Abstraction和 Ehcache。我正在使用@Cacheable 注解来标注一个目标方法,如下所示:

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

这是我的 jUnit 测试:

public class ServiceTest extends AbstractJUnit4SpringContextTests{

    @Resource
    private DataService dataService;

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

当我使用jUnit测试进行调试时,情况并不理想。它会抛出一个如下所示的IllegalArgumentException

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)

我有以下配置:

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>

注意:如果我在@Cacheable注释中没有指定“key”,它会正常工作。

我是否忘记了需要指定的内容?例如配置或注释?


如果只有一个参数,您实际上不需要指定键。 - xedo
你能加上这个测试吗? - xedo
您在 dataService.findByDirector() 缺少参数。 - xedo
请问是哪个参数? - Green Lei
@GreenLei System.err.println(dataService.findByDirector()); 你没有向该方法传递任何 name 参数。例如,应该是 System.err.println(dataService.findByDirector("John Smith")); - Guillaume Polet
显示剩余2条评论
4个回答

15

我遇到了同样的问题,根本原因是在测试中参数确实为null,所以只需添加非null检查即可。

@Cacheable(value="movieFindCache", key="#p0", condition="#p0!=null")
public String findByDirector(String name) {...}

13

3
我曾经在使用ehCache 3时遇到过这种情况。在我的本地环境中,使用参数名称作为键是可以正常工作的,例如:
// this would fail
@Cacheable(value="movieFindCache", key="name")
    public String findByDirector(String name) {

但是在测试环境中部署时,我会收到错误提示。我通过从具有单个参数的方法的@Cacheable注释中删除key属性来解决了这个问题:

// this worked
@Cacheable("movieFindCache")
    public String findByDirector(String name) {

-3

IllegalArgumentException 的信息非常明确。Spring 文档中的 以下表格 指示了可用于使用参数名称的内容。

相关的 javac 选项已记录。在此情况下,您需要使用 -g 选项。


“following table” 的链接并未指向一个表格。 - Julien Kronegg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接