Affects: Spring Context 4.3.4 and higher
Trying to use @CachePut
on a method that might return null
.
@CachePut(cacheNames = Constants.Caches.USER, key = "#result.id", unless = "#result == null")
public MyObject doSomething();
You would expect the key expression not to be evaluated if the unless
condition is true
but this is not happening. The key is being evaluated before the unless
condition is evaluated which leads to a
org.springframework.expression.spel.SpelEvaluationException: EL1007E:(pos 0): Property or field 'id' cannot be found on null
if (cacheHit != null && cachePutRequests.isEmpty() && !hasCachePut(contexts)) {
// If there are no put requests, just use the cache hit
cacheValue = cacheHit.get();
returnValue = wrapCacheValue(method, cacheValue);
}
else {
// Invoke the method if we don't have a cache hit
returnValue = invokeOperation(invoker);
cacheValue = unwrapReturnValue(returnValue);
}
// Collect any explicit @CachePuts
collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);
// Process any collected put requests, either from @CachePut or a @Cacheable miss
for (CachePutRequest cachePutRequest : cachePutRequests) {
cachePutRequest.apply(cacheValue);
}
The collectPutRequests
tries to evaluate the key if the condition
passes (there is no condition). I think the keys need to be evaluated only if unless
is false
?
Comment From: solarmicrobe
+1 Just hit this today. Luckily for me it is in a demo application and I can submit with just a javadoc on my function.
Comment From: sbrannen
I've edited your comment to improve the formatting. You might want to check out this Mastering Markdown guide for future reference.
Comment From: snicoll
Closing in favor of PR #22769