JayabalanAaron
JayabalanAaron

Reputation: 365

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

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>

Upvotes: 2

Views: 4697

Answers (2)

RotS
RotS

Reputation: 2410

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);

Upvotes: 0

Michael Piefel
Michael Piefel

Reputation: 19968

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.

Upvotes: 2

Related Questions