EhCache缓存对象修改
EhCache cached object modification
我必须使用 EhCache 实现缓存。基本要求是,我必须将该缓存对象保留固定时间间隔(现在在下面的代码中为 1 小时)。所以,我实现了如下代码:
示例域对象:
import lombok.*;
@Getter
@Setter
@ToString
@AllArgsConstructor
public class City implements Serializable {
public String name;
public String country;
public int population;
}
缓存管理器class:
import net.sf.ehcache.*;
public class JsonObjCacheManager {
private static final Logger logger = LoggerFactory.getLogger(JsonObjCacheManager.class);
private CacheManager manager;
private Cache objectCache;
public JsonObjCacheManager(){
manager = CacheManager.create();
objectCache = manager.getCache("jsonDocCache");
if( objectCache == null){
objectCache = new Cache(
new CacheConfiguration("jsonDocCache", 1000)
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
.eternal(false)
.timeToLiveSeconds(60 * 60)
.timeToIdleSeconds(0)
.diskExpiryThreadIntervalSeconds(0)
.persistence(new PersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.LOCALTEMPSWAP)));
objectCache.disableDynamicFeatures();
manager.addCache(objectCache);
}
}
public List<String> getKeys() { return objectCache.getKeys();}
public void clearCache(){
manager.removeAllCaches();
}
public void putInCache(String key, Object value){
try{
objectCache.put(new Element(key, value));
}catch (CacheException e){
logger.error(String.format( "Problem occurred while putting data into cache: %s", e.getMessage()));
}
}
public Object retrieveFromCache(String key){
try {
Element element = objectCache.get(key);
if(element != null)
return element.getObjectValue();
}catch (CacheException ce){
logger.error(String.format("Problem occurred while trying to retrieveSpecific from cache: %s", ce.getMessage()));
}
return null;
}
}
它非常正确地缓存和检索值。但我的要求是,我必须修改我从缓存中为给定键检索的对象。我得到的是,如果我修改了从缓存中检索到的对象,那么该键的缓存对象也会被修改。
示例如下:
public class Application {
public static void main(String[] args) {
JsonObjCacheManager manager = new JsonObjCacheManager();
final City city1 = new City("ATL","USA",12100);
final City city2 = new City("FL","USA",12000);
manager.putInCache(city1.getName(), city1);
manager.putInCache(city2.getName(), city2);
System.out.println(manager.getKeys());
for(String key: manager.getKeys()){
System.out.println(key + ": "+ manager.retrieveFromCache(key));
}
City cityFromCache = (City) manager.retrieveFromCache(city1.getName());
cityFromCache.setName("KTM");
cityFromCache.setCountry("NPL");
System.out.println(manager.getKeys());
for(String key: manager.getKeys()){
System.out.println(key + ": "+ manager.retrieveFromCache(key));
}
}
}
我得到的输出是:
[ATL, FL]
ATL: City(name=ATL, country=USA, population=12100)
FL: City(name=FL, country=USA, population=12000)
[ATL, FL]
ATL: City(name=KTM, country=NPL, population=12100)
FL: City(name=FL, country=USA, population=12000)
这意味着,每当我检索和修改给定键的对象时,它也会反映在缓存值中。
我的要求是,给定键的缓存对象不应被修改。有什么办法可以做到这一点?还是实现 EhCache 的方式不正确?或者我遗漏了一些基本原则?
我正在使用 EhCache V2.10.3
谢谢!
当您使用将其数据存储在堆上并具有直接对象引用的缓存时,您需要在使用之前复制该对象。
一般来说,在将对象引用移交给缓存(或您无法控制的任何其他人)后不要改变值是一个好习惯。
一些缓存确实有复制机制来保护缓存值不被修改。例如。在 EHCache3 中,您可以添加复印机,请参阅 Serializers and Copiers。
或者,改变你的设计:当你需要改变值时,也许你可以将值分成两个对象,一个是缓存,一个包含需要改变的数据,使后者包含第一.
我必须使用 EhCache 实现缓存。基本要求是,我必须将该缓存对象保留固定时间间隔(现在在下面的代码中为 1 小时)。所以,我实现了如下代码:
示例域对象:
import lombok.*;
@Getter
@Setter
@ToString
@AllArgsConstructor
public class City implements Serializable {
public String name;
public String country;
public int population;
}
缓存管理器class:
import net.sf.ehcache.*;
public class JsonObjCacheManager {
private static final Logger logger = LoggerFactory.getLogger(JsonObjCacheManager.class);
private CacheManager manager;
private Cache objectCache;
public JsonObjCacheManager(){
manager = CacheManager.create();
objectCache = manager.getCache("jsonDocCache");
if( objectCache == null){
objectCache = new Cache(
new CacheConfiguration("jsonDocCache", 1000)
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
.eternal(false)
.timeToLiveSeconds(60 * 60)
.timeToIdleSeconds(0)
.diskExpiryThreadIntervalSeconds(0)
.persistence(new PersistenceConfiguration().strategy(PersistenceConfiguration.Strategy.LOCALTEMPSWAP)));
objectCache.disableDynamicFeatures();
manager.addCache(objectCache);
}
}
public List<String> getKeys() { return objectCache.getKeys();}
public void clearCache(){
manager.removeAllCaches();
}
public void putInCache(String key, Object value){
try{
objectCache.put(new Element(key, value));
}catch (CacheException e){
logger.error(String.format( "Problem occurred while putting data into cache: %s", e.getMessage()));
}
}
public Object retrieveFromCache(String key){
try {
Element element = objectCache.get(key);
if(element != null)
return element.getObjectValue();
}catch (CacheException ce){
logger.error(String.format("Problem occurred while trying to retrieveSpecific from cache: %s", ce.getMessage()));
}
return null;
}
}
它非常正确地缓存和检索值。但我的要求是,我必须修改我从缓存中为给定键检索的对象。我得到的是,如果我修改了从缓存中检索到的对象,那么该键的缓存对象也会被修改。
示例如下:
public class Application {
public static void main(String[] args) {
JsonObjCacheManager manager = new JsonObjCacheManager();
final City city1 = new City("ATL","USA",12100);
final City city2 = new City("FL","USA",12000);
manager.putInCache(city1.getName(), city1);
manager.putInCache(city2.getName(), city2);
System.out.println(manager.getKeys());
for(String key: manager.getKeys()){
System.out.println(key + ": "+ manager.retrieveFromCache(key));
}
City cityFromCache = (City) manager.retrieveFromCache(city1.getName());
cityFromCache.setName("KTM");
cityFromCache.setCountry("NPL");
System.out.println(manager.getKeys());
for(String key: manager.getKeys()){
System.out.println(key + ": "+ manager.retrieveFromCache(key));
}
}
}
我得到的输出是:
[ATL, FL]
ATL: City(name=ATL, country=USA, population=12100)
FL: City(name=FL, country=USA, population=12000)
[ATL, FL]
ATL: City(name=KTM, country=NPL, population=12100)
FL: City(name=FL, country=USA, population=12000)
这意味着,每当我检索和修改给定键的对象时,它也会反映在缓存值中。
我的要求是,给定键的缓存对象不应被修改。有什么办法可以做到这一点?还是实现 EhCache 的方式不正确?或者我遗漏了一些基本原则?
我正在使用 EhCache V2.10.3
谢谢!
当您使用将其数据存储在堆上并具有直接对象引用的缓存时,您需要在使用之前复制该对象。
一般来说,在将对象引用移交给缓存(或您无法控制的任何其他人)后不要改变值是一个好习惯。
一些缓存确实有复制机制来保护缓存值不被修改。例如。在 EHCache3 中,您可以添加复印机,请参阅 Serializers and Copiers。
或者,改变你的设计:当你需要改变值时,也许你可以将值分成两个对象,一个是缓存,一个包含需要改变的数据,使后者包含第一.