spring @Cacheable with Ehcache, spel find null for valid object
Asked Answered
S

2

2

I have a similar problem which but sometimes it works. The error described only happens once in a while.

I am using spring 3.2.5 and ehcache 2.6.5.

Exception trace:

org.springframework.expression.spel.SpelEvaluationException: EL1007E:(pos 0): Field or property 'applicationID' cannot be found on null
        at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:213)
        at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:85)
        at org.springframework.expression.spel.ast.PropertyOrFieldReference.access$000(PropertyOrFieldReference.java:43)
        at org.springframework.expression.spel.ast.PropertyOrFieldReference$AccessorLValue.getValue(PropertyOrFieldReference.java:346)
        at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:82)
        at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93)
        at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:89)
        at org.springframework.cache.interceptor.ExpressionEvaluator.key(ExpressionEvaluator.java:95)
        at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.generateKey(CacheAspectSupport.java:452)
        at org.springframework.cache.interceptor.CacheAspectSupport.inspectCacheables(CacheAspectSupport.java:281)
        at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:199)
        at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:66)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        at com.sun.proxy.$Proxy85.getMailOrigin(Unknown Source)
        at com.myApplication.MailFilterServiceImpl.isValid(ApplicationServiceImpl.java:134)

My caching code is a follows:

MailFilterServiceImpl
    @Cacheable(value="mailClientsCache", key="#mb.applicationID")
        public MailClientBean getMailOrigin(MailBean mb){}

When this happens: When I have a jenkins configured to build and autodeploy to tomcat7 / when I use maven to build in the eclipse WS and deploy to tomcat7.

When this works perfectly: After it has failed once, if I edit the MailFilterServiceImpl.java simply with some spaces to make it recompile in eclipse and restart the tomcat7 server.

I need to make it work in a CI scenario.

[Update] Setting compiler option debug:true works around this problem. The optimized doesnt seem to have any say.

<debug>true</debug>
<optimize>true</optimize>
Subsequent answered 19/6, 2014 at 7:30 Comment(0)
C
2

Your description makes one thing clear: It does not work when you compile with javac, but it does work with the Eclipse compiler ecj. You might be compiling without debugging information.

Chryso answered 19/6, 2014 at 7:40 Comment(7)
Could the order of compiling the @Cacheable annotated classes be a problem, ie when I compile from eclipse, its the last class to be compiled?Subsequent
The order is likely to be of no concern. Please check your Maven configuration for Java compilation without debugging information; you might want to post the relevant bits here.Chryso
My pom compiler config had debug:false, added debug:true and it works after maven build, updated post. Have jdk=7u55(IcedTea 2.4.7)64bit on linux.Subsequent
That’s not a work-around, that’s the solution. SpEL cannot access arguments by name if that information is not available. You need at least -g:vars.Chryso
Thanks, but feel this could have been documented under SpEL. Its strange that this is a requirement but not documented.Subsequent
Once you think it through, it becomes obvious that it cannot be otherwise. However, I agree wholeheartedly that such a pitfall should be mentioned in the documentation.Chryso
docs.spring.io/spring-framework/docs/3.2.5.RELEASE/… table 29.1 vaguely mentions thisCecilia
G
0

I was also encountering a SpelEvaluationException: Field or property 'xxx' cannot be found on null in the Spring Expression Language (SpEL) of my @Cacheable annotation. I looked in debug mode to ensure that the passed argument was not null, I added a Cacheable condition to ensure its non-nullity, I added @NonNull annotations, so this made no sense that the property was detected as null.

For me, the solution was to rename the property in the SpEL of the Cacheable annotation. I then decided to use the lowercase version of the argument's classname instead of some other name. I think that Spring is not reusing the actual argument name as it is written in the method signature, Spring is making its own assumption about the argument name, by turning the classname into lowercase or something similar.

This works:

@Cacheable(value = FIND_X_BY_Y_CACHE, key = "#myArgument.id")
Object findXByY(MyArgument myArgument); 

This doesn't work:

@Cacheable(value = FIND_X_BY_Y_CACHE, key = "#anotherName.id")
Object findXByY(MyArgument anotherName);
Goby answered 3/3, 2023 at 9:27 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.