Allow null values to be cached with @CacheResult
Even though the JSR-107 spec forbids to store null values, our cache abstraction allows that behaviour with a special handled (and this is the default behaviour). While this was working fine with our own set of annotations, the JSR-107 interceptor counterpart was interpreting the spec sensu strictu. We now allow for that special case as well. Issue: SPR-13641
This commit is contained in:
@@ -38,6 +38,11 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
|
|||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object cacheNull(Object arg1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object conditional(int field) {
|
public Object conditional(int field) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -58,6 +58,12 @@ public class AnnotatedJCacheableService implements JCacheableService<Long> {
|
|||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@CacheResult
|
||||||
|
public Long cacheNull(String id) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CacheResult(exceptionCacheName = "exception", nonCachedExceptions = NullPointerException.class)
|
@CacheResult(exceptionCacheName = "exception", nonCachedExceptions = NullPointerException.class)
|
||||||
public Long cacheWithException(@CacheKey String id, boolean matchFilter) {
|
public Long cacheWithException(@CacheKey String id, boolean matchFilter) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -26,6 +26,8 @@ public interface CacheableService<T> {
|
|||||||
|
|
||||||
T cache(Object arg1);
|
T cache(Object arg1);
|
||||||
|
|
||||||
|
T cacheNull(Object arg1);
|
||||||
|
|
||||||
void invalidate(Object arg1);
|
void invalidate(Object arg1);
|
||||||
|
|
||||||
void evictEarly(Object arg1);
|
void evictEarly(Object arg1);
|
||||||
|
|||||||
@@ -40,6 +40,12 @@ public class DefaultCacheableService implements CacheableService<Long> {
|
|||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Cacheable("testCache")
|
||||||
|
public Long cacheNull(Object arg1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict("testCache")
|
@CacheEvict("testCache")
|
||||||
public void invalidate(Object arg1) {
|
public void invalidate(Object arg1) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -59,9 +59,7 @@ class CacheResultInterceptor extends AbstractKeyCacheInterceptor<CacheResultOper
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Object invocationResult = invoker.invoke();
|
Object invocationResult = invoker.invoke();
|
||||||
if (invocationResult != null) {
|
cache.put(cacheKey, invocationResult);
|
||||||
cache.put(cacheKey, invocationResult);
|
|
||||||
}
|
|
||||||
return invocationResult;
|
return invocationResult;
|
||||||
}
|
}
|
||||||
catch (CacheOperationInvoker.ThrowableWrapper ex) {
|
catch (CacheOperationInvoker.ThrowableWrapper ex) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -67,6 +67,23 @@ public abstract class AbstractJCacheAnnotationTests {
|
|||||||
assertSame(first, second);
|
assertSame(first, second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cacheNull() {
|
||||||
|
Cache cache = getCache(DEFAULT_CACHE);
|
||||||
|
|
||||||
|
String keyItem = name.getMethodName();
|
||||||
|
assertNull(cache.get(keyItem));
|
||||||
|
|
||||||
|
Object first = service.cacheNull(keyItem);
|
||||||
|
Object second = service.cacheNull(keyItem);
|
||||||
|
assertSame(first, second);
|
||||||
|
|
||||||
|
Cache.ValueWrapper wrapper = cache.get(keyItem);
|
||||||
|
assertNotNull(wrapper);
|
||||||
|
assertSame(first, wrapper.get());
|
||||||
|
assertNull("Cached value should be null", wrapper.get());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void cacheException() {
|
public void cacheException() {
|
||||||
String keyItem = name.getMethodName();
|
String keyItem = name.getMethodName();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -25,6 +25,8 @@ public interface JCacheableService<T> {
|
|||||||
|
|
||||||
T cache(String id);
|
T cache(String id);
|
||||||
|
|
||||||
|
T cacheNull(String id);
|
||||||
|
|
||||||
T cacheWithException(String id, boolean matchFilter);
|
T cacheWithException(String id, boolean matchFilter);
|
||||||
|
|
||||||
T cacheWithCheckedException(String id, boolean matchFilter) throws IOException;
|
T cacheWithCheckedException(String id, boolean matchFilter) throws IOException;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -57,6 +57,12 @@ public class AnnotatedJCacheableService implements JCacheableService<Long> {
|
|||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@CacheResult
|
||||||
|
public Long cacheNull(String id) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CacheResult(exceptionCacheName = "exception", nonCachedExceptions = NullPointerException.class)
|
@CacheResult(exceptionCacheName = "exception", nonCachedExceptions = NullPointerException.class)
|
||||||
public Long cacheWithException(@CacheKey String id, boolean matchFilter) {
|
public Long cacheWithException(@CacheKey String id, boolean matchFilter) {
|
||||||
|
|||||||
@@ -89,6 +89,21 @@ public abstract class AbstractAnnotationTests {
|
|||||||
assertSame(r1, r3);
|
assertSame(r1, r3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testCacheableNull(CacheableService<?> service) throws Exception {
|
||||||
|
Object o1 = new Object();
|
||||||
|
assertNull(cm.getCache("testCache").get(o1));
|
||||||
|
|
||||||
|
Object r1 = service.cacheNull(o1);
|
||||||
|
Object r2 = service.cacheNull(o1);
|
||||||
|
Object r3 = service.cacheNull(o1);
|
||||||
|
|
||||||
|
assertSame(r1, r2);
|
||||||
|
assertSame(r1, r3);
|
||||||
|
|
||||||
|
assertEquals(r3, cm.getCache("testCache").get(o1).get());
|
||||||
|
assertNull("Cached value should be null", r3);
|
||||||
|
}
|
||||||
|
|
||||||
public void testEvict(CacheableService<?> service) throws Exception {
|
public void testEvict(CacheableService<?> service) throws Exception {
|
||||||
Object o1 = new Object();
|
Object o1 = new Object();
|
||||||
|
|
||||||
@@ -457,6 +472,11 @@ public abstract class AbstractAnnotationTests {
|
|||||||
testCacheable(cs);
|
testCacheable(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCacheableNull() throws Exception {
|
||||||
|
testCacheableNull(cs);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidate() throws Exception {
|
public void testInvalidate() throws Exception {
|
||||||
testEvict(cs);
|
testEvict(cs);
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
|
|||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object cacheNull(Object arg1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object conditional(int field) {
|
public Object conditional(int field) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -27,6 +27,8 @@ public interface CacheableService<T> {
|
|||||||
|
|
||||||
T cache(Object arg1);
|
T cache(Object arg1);
|
||||||
|
|
||||||
|
T cacheNull(Object arg1);
|
||||||
|
|
||||||
void invalidate(Object arg1);
|
void invalidate(Object arg1);
|
||||||
|
|
||||||
void evictEarly(Object arg1);
|
void evictEarly(Object arg1);
|
||||||
|
|||||||
@@ -41,6 +41,12 @@ public class DefaultCacheableService implements CacheableService<Long> {
|
|||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Cacheable("testCache")
|
||||||
|
public Long cacheNull(Object arg1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict("testCache")
|
@CacheEvict("testCache")
|
||||||
public void invalidate(Object arg1) {
|
public void invalidate(Object arg1) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
<cache:advice id="cacheAdviceInterface" cache-manager="cacheManager">
|
<cache:advice id="cacheAdviceInterface" cache-manager="cacheManager">
|
||||||
<cache:caching cache="testCache">
|
<cache:caching cache="testCache">
|
||||||
<cache:cacheable method="cache"/>
|
<cache:cacheable method="cache"/>
|
||||||
|
<cache:cacheable method="cacheNull"/>
|
||||||
<cache:cacheable method="conditional" condition="#classField == 3"/>
|
<cache:cacheable method="conditional" condition="#classField == 3"/>
|
||||||
<cache:cacheable method="unless" unless="#result > 10"/>
|
<cache:cacheable method="unless" unless="#result > 10"/>
|
||||||
<cache:cacheable method="key" key="#p0"/>
|
<cache:cacheable method="key" key="#p0"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user