Store by value support for ConcurrentMapCacheManager
ConcurrentMapCacheManager and ConcurrentMapCache now support the serialization of cache entries via a new `storeByValue` attribute. If it is explicitly enabled, the cache value is first serialized and that content is stored in the cache. The net result is that any further change made on the object returned from the annotated method is not applied on the copy held in the cache. Issue: SPR-13758
This commit is contained in:
@@ -211,7 +211,7 @@ public abstract class AbstractCacheTests<T extends Cache> {
|
||||
results.forEach(r -> assertThat(r, is(1))); // Only one method got invoked
|
||||
}
|
||||
|
||||
private String createRandomKey() {
|
||||
protected String createRandomKey() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class ConcurrentMapCacheManagerTests {
|
||||
|
||||
@@ -120,4 +121,21 @@ public class ConcurrentMapCacheManagerTests {
|
||||
assertNull(cache1y.get("key3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChangeStoreByValue() {
|
||||
ConcurrentMapCacheManager cm = new ConcurrentMapCacheManager("c1", "c2");
|
||||
assertFalse(cm.isStoreByValue());
|
||||
Cache cache1 = cm.getCache("c1");
|
||||
assertTrue(cache1 instanceof ConcurrentMapCache);
|
||||
assertFalse(((ConcurrentMapCache)cache1).isStoreByValue());
|
||||
cache1.put("key", "value");
|
||||
|
||||
cm.setStoreByValue(true);
|
||||
assertTrue(cm.isStoreByValue());
|
||||
Cache cache1x = cm.getCache("c1");
|
||||
assertTrue(cache1x instanceof ConcurrentMapCache);
|
||||
assertTrue(cache1x != cache1);
|
||||
assertNull(cache1x.get("key"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,13 +16,19 @@
|
||||
|
||||
package org.springframework.cache.concurrent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.cache.AbstractCacheTests;
|
||||
import org.springframework.core.serializer.support.SerializationDelegate;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
@@ -53,4 +59,53 @@ public class ConcurrentMapCacheTests extends AbstractCacheTests<ConcurrentMapCac
|
||||
return this.nativeCache;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsStoreByReferenceByDefault() {
|
||||
assertFalse(this.cache.isStoreByValue());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testSerializer() {
|
||||
ConcurrentMapCache serializeCache = createCacheWithStoreByValue();
|
||||
assertTrue(serializeCache.isStoreByValue());
|
||||
|
||||
Object key = createRandomKey();
|
||||
List<String> content = new ArrayList<>();
|
||||
content.addAll(Arrays.asList("one", "two", "three"));
|
||||
serializeCache.put(key, content);
|
||||
content.remove(0);
|
||||
List<String> entry = (List<String>) serializeCache.get(key).get();
|
||||
assertEquals(3, entry.size());
|
||||
assertEquals("one", entry.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonSerializableContent() {
|
||||
ConcurrentMapCache serializeCache = createCacheWithStoreByValue();
|
||||
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectMessage("Failed to serialize");
|
||||
thrown.expectMessage(this.cache.getClass().getName());
|
||||
serializeCache.put(createRandomKey(), this.cache);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidSerializedContent() {
|
||||
ConcurrentMapCache serializeCache = createCacheWithStoreByValue();
|
||||
|
||||
String key = createRandomKey();
|
||||
this.nativeCache.put(key, "Some garbage");
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectMessage("Failed to deserialize");
|
||||
thrown.expectMessage("Some garbage");
|
||||
serializeCache.get(key);
|
||||
}
|
||||
|
||||
|
||||
private ConcurrentMapCache createCacheWithStoreByValue() {
|
||||
return new ConcurrentMapCache(CACHE_NAME, nativeCache, true,
|
||||
new SerializationDelegate(ConcurrentMapCacheTests.class.getClassLoader()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user