Spring cache @带键的CacheExit="#id";抛出NullPointerException

Spring cache @带键的CacheExit="#id";抛出NullPointerException,spring-cache,google-guava-cache,Spring Cache,Google Guava Cache,我试图将Spring缓存注释@Cacheable和@cacheexecute与GuavacheManager一起使用 我用这两个测试创建了一个测试用例: cachesById-验证对用@Cacheable注释的方法的两次调用是否返回相同的对象 execute-验证如果在两次调用之间调用了带有@cacheexecute注释的方法,则返回两个不同的实例 当我没有为@cacheexecute指定键时,这两种方法都可以正常工作,但是当我指定键时,会出现以下异常: java.lang.NullPointe

我试图将Spring缓存注释
@Cacheable
@cacheexecute
与GuavacheManager一起使用

我用这两个测试创建了一个测试用例:

  • cachesById
    -验证对用
    @Cacheable
    注释的方法的两次调用是否返回相同的对象
  • execute
    -验证如果在两次调用之间调用了带有
    @cacheexecute
    注释的方法,则返回两个不同的实例
  • 当我没有为
    @cacheexecute
    指定键时,这两种方法都可以正常工作,但是当我指定键时,会出现以下异常:

    java.lang.NullPointerException
        at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:210)
        at com.google.common.cache.LocalCache$LocalManualCache.invalidate(LocalCache.java:4764)
        at org.springframework.cache.guava.GuavaCache.evict(GuavaCache.java:135)
        at org.springframework.cache.interceptor.AbstractCacheInvoker.doEvict(AbstractCacheInvoker.java:95)
        at org.springframework.cache.interceptor.CacheAspectSupport.performCacheEvict(CacheAspectSupport.java:409)
        at org.springframework.cache.interceptor.CacheAspectSupport.processCacheEvicts(CacheAspectSupport.java:392)
        at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:362)
        at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:299)
        at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
        at com.myorg.caching.CacheTest$Repo$$EnhancerBySpringCGLIB$$eed50f3e.update(<generated>)
        at com.myorg.caching.CacheTest.evict(CacheTest.java:50)
    
    但是,如果我改变了,测试就通过了

    @CacheEvict(value = CACHE_NAME, key = "#id")
    public void update(Entity e) {
    
    进入:

    ..但是我没有找到需要为
    实体
    指定缓存键的地方。有人知道我错过了什么吗


    谢谢

    您必须从中修复组件类

    @Component
    public static class Repo {
    
        @Cacheable(value = CACHE_NAME, key = "#id")
        public Entity getEntity(int id) {
            return new Entity(id);
        }
    
        @CacheEvict(value = CACHE_NAME, key = "#id")
        public void update(Entity e) {    
        }
    }
    

    为什么??在使用
    int-id
    缓存
    Entity
    对象的
    getEntity
    方法中,必须将相同的
    int-id
    传递到
    @cacheexecute
    注释方法中。您不必更改方法的签名——通过使用SPEL,您可以“进入”实体并使用其id字段


    希望我能帮上忙。

    您必须从

    @Component
    public static class Repo {
    
        @Cacheable(value = CACHE_NAME, key = "#id")
        public Entity getEntity(int id) {
            return new Entity(id);
        }
    
        @CacheEvict(value = CACHE_NAME, key = "#id")
        public void update(Entity e) {    
        }
    }
    

    为什么??在使用
    int-id
    缓存
    Entity
    对象的
    getEntity
    方法中,必须将相同的
    int-id
    传递到
    @cacheexecute
    注释方法中。您不必更改方法的签名——通过使用SPEL,您可以“进入”实体并使用其id字段


    希望我能帮上忙。

    没有名为
    id
    的方法参数,所以它指的是什么,在java中没有任何参数。您有一个名为
    e
    Entity
    类型的参数,该参数可能具有
    id
    属性。将
    #id
    更改为
    #e.id
    。我建议阅读spring缓存文档。没有名为
    id
    的方法参数,所以它指的是什么,在java中没有任何名称。您有一个名为
    e
    Entity
    类型的参数,该参数可能具有
    id
    属性。将
    #id
    更改为
    #e.id
    。我建议阅读spring缓存文档。为什么在
    key=“#e?.id”
    @Thanga中有
    ,实体e(
    #e
    )可能为空,因此访问
    id
    属性将导致
    NullPointerException
    <代码>?符号表示此属性可能为null,只有当它不是null时,程序才应该访问
    id
    。请看:谢谢您的解释@Trynkiewicz Mariusz。。这对我没用。它只是将异常更改为NPE为什么在
    key=“#e?.id”
    @Thanga中存在
    实体e(
    #e
    )可能为空,因此访问
    id
    属性将导致
    NullPointerException
    <代码>?符号表示此属性可能为null,只有当它不是null时,程序才应该访问
    id
    。请看:谢谢您的解释@Trynkiewicz Mariusz。。这对我没用。它只是将异常更改为NPE
    @Component
    public static class Repo {
    
        @Cacheable(value = CACHE_NAME, key = "#id")
        public Entity getEntity(int id) {
            return new Entity(id);
        }
    
        @CacheEvict(value = CACHE_NAME, key = "#id")
        public void update(Entity e) {    
        }
    }
    
    @Component
    public static class Repo {
    
        @Cacheable(value = CACHE_NAME, key = "#id")
        public Entity getEntity(int id) {
            return new Entity(id);
        }
    
        @CacheEvict(value = CACHE_NAME, key = "#e?.id")
        public void update(Entity e) {    
        }
    }