Results 1 to 5 of 5

Thread: How to construct a key for cache in @Cacheable annotation

  1. #1
    Join Date
    Jan 2012
    Posts
    16

    Default How to construct a key for cache in @Cacheable annotation

    Hi there,

    Another question about spring cache abstraction @Cacheable annotation:
    Code:
    public PersonService {
       ...
       public string getType() {
          return "PersonService";
       }
       
        @Cacheable(value = "defaultCache")
        public Person findPerson(int id)  {
                return getSession().getPerson(id);
        }
    
    }
    Can I construct the cache key to be getType() + id using SpEL in the @cacheable annotation?
    Thanks,

    David

  2. #2
    Join Date
    Jun 2011
    Posts
    35

    Default

    This is without testing it, but I think you should be able to do somthing like this
    Code:
    @Cacheable(value = "defaultCache", key="#root.target.getType() + #id")
    See the "28.3.1.2 Custom Key Generation Declaration" and "28.3.1.4 Available caching SpEL evaluation context" in the Spring reference manual [1].

    [1] http://static.springsource.org/sprin...tml/cache.html

    Best regards
    Pontus Ullgren

  3. #3
    Join Date
    Jan 2012
    Posts
    16

    Default

    Thanks,

    Code:
    key="#root.target.getType()"
    worked. One observation though, if I need to call the method from the returned object by getType(), say,
    Code:
    key="#root.target.getType().getName()"
    , I'll get an error:

    org.springframework.expression.spel.SpelEvaluation Exception: EL1004Epos 23): Method call: Method getName() cannot be found on com.example.Person type
    at org.springframework.expression.spel.ast.MethodRefe rence.findAccessorForMethod(MethodReference.java:1 82)
    at org.springframework.expression.spel.ast.MethodRefe rence.getValueInternal(MethodReference.java:106)
    at org.springframework.expression.spel.ast.CompoundEx pression.getValueInternal(CompoundExpression.java: 57)
    at org.springframework.expression.spel.ast.OpPlus.get ValueInternal(OpPlus.java:62)
    at org.springframework.expression.spel.ast.OpPlus.get ValueInternal(OpPlus.java:62)
    at org.springframework.expression.spel.ast.SpelNodeIm pl.getValue(SpelNodeImpl.java:93)
    at org.springframework.expression.spel.standard.SpelE xpression.getValue(SpelExpression.java:88)
    at org.springframework.cache.interceptor.ExpressionEv aluator.key(ExpressionEvaluator.java:80)
    at org.springframework.cache.interceptor.CacheAspectS upport$CacheOperationContext.generateKey(CacheAspe ctSupport.java:464)
    at org.springframework.cache.interceptor.CacheAspectS upport.inspectCacheables(CacheAspectSupport.java:2 91)
    at org.springframework.cache.interceptor.CacheAspectS upport.execute(CacheAspectSupport.java:198)
    at org.springframework.cache.interceptor.CacheInterce ptor.invoke(CacheInterceptor.java:66)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :172)
    at org.springframework.aop.framework.Cglib2AopProxy$D ynamicAdvisedInterceptor.intercept(Cglib2AopProxy. java:622)
    at com.activx.om.util.dao.TorqueDAO$$EnhancerByCGLIB$ $190b8d3a.find(<generated>)
    at com.activx.om.util.dao.TorqueDAOTest.testFind(Torq ueDAOTest.java:76)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknow n Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Un known Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runRefle ctiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallabl e.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExpl osively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod .evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.e valuate(RunBefores.java:28)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunne r.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild( BlockJUnit4ClassRunner.java:69)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild( BlockJUnit4ClassRunner.java:48)
    at org.junit.runners.ParentRunner$3.run(ParentRunner. java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRu nner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentR unner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRu nner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRu nner.java:222)
    at org.junit.internal.runners.statements.RunBefores.e valuate(RunBefores.java:28)
    at org.junit.runners.ParentRunner.run(ParentRunner.ja va:292)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestR eference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecutio n.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.main(RemoteTestRunner.java:197)

  4. #4
    Join Date
    Jun 2011
    Posts
    35

    Default

    From the posted stack trace it seems you have changed your code since your original post.

    You need to make sure that the object returned from getType() has a getName() method.

    BR
    Pontus

  5. #5
    Join Date
    Jan 2012
    Posts
    16

    Default

    The returned object (Class) does have a getName method, if I have another method like:
    Code:
    public String getTypeName() {
       return getType().getName();
    }
    it'll work, but I guess Spring can't call the returned object's method from the proxy it generated. It's trying to access the returned object in the cached method, rather than accessing the method in the class.
    But it's no biggie, I can get it to work, just something I observed as a heads-up for others.
    Thanks,

    David

    Quote Originally Posted by ullgren View Post
    From the posted stack trace it seems you have changed your code since your original post.

    You need to make sure that the
    object returned from getType() has a getName() method.

    BR
    Pontus

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •