Spring @Cacheable с Ehcache, spel найти ноль для допустимого объекта

У меня похожая проблема, но иногда она работает. Описанная ошибка происходит только время от времени.

Я использую весной 3.2.5 и ehcache 2.6.5.

Трассировка исключения:

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)

Мой кеширующий код выглядит следующим образом:

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

Когда это происходит: когда у меня есть jenkins, настроенный для сборки и автоматического развертывания на tomcat7 / когда я использую maven для сборки в eclipse WS и развертывания на tomcat7.

Когда это работает идеально: после того, как он один раз завершился неудачей, если я отредактирую MailFilterServiceImpl.java просто с некоторыми пробелами, чтобы он перекомпилировался в eclipse и перезапустил сервер tomcat7.

Мне нужно, чтобы это работало в сценарии CI.

[Update] Установка опции компилятора debug:true обходит эту проблему. Оптимизированный, похоже, не имеет права голоса.

<debug>true</debug>
<optimize>true</optimize>

2 ответа

Решение

Ваше описание проясняет одну вещь: оно не работает при компиляции с javac, но он работает с компилятором Eclipse ecj, Возможно, вы компилируете без отладочной информации.

Я также столкнулся сна языке выражений Spring (SpEL) моей аннотации @Cacheable. Я посмотрел в режиме отладки, чтобы убедиться, что переданный аргумент не является нулевым, я добавил условие Cacheable, чтобы гарантировать его ненулевое значение, я добавил аннотации @NonNull, так что это не имело смысла, что свойство было обнаружено как пустое.

Для меня решением было переименовать свойство в SpEL аннотации Cacheable. Затем я решил использовать строчную версию имени класса аргумента вместо какого-либо другого имени. Я думаю, что Spring не повторно использует фактическое имя аргумента, как оно написано в сигнатуре метода, Spring делает свое собственное предположение об имени аргумента, превращая имя класса в нижний регистр или что-то подобное.

Это работает:

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

Это не работает:

      @Cacheable(value = FIND_X_BY_Y_CACHE, key = "#anotherName.id")
Object findXByY(MyArgument anotherName);
Другие вопросы по тегам