2016-08-25 15 views
0

私はキャッシュバックエンドとしてRedis/JDKシリアライゼーションでSpring Cacheを使用しています。結果がキャッシュされ、キャッシュにいくつかの値が設定されたメソッドがあります。私のアプリケーションのアップデートでは、キャッシュされたオブジェクトのクラスをJavaの逆シリアル化を中断する方法で変更しています(メンバーのタイプをListからSetに変更)。今私のキャッシュされたメソッドへの呼び出しはorg.springframework.data.redis.serializer.SerializationExceptionで失敗します。キャッシュのシリアル化エラーを無視するようにSpring Cacheを設定するにはどうすればよいですか?

@Cacheable(cacheNames = "myCache", cacheManager = "myCacheManager) 
public SomeObject myCachedMethod(String param) { 
    return ...; 
} 

スタックトレース:

Caused by: org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.lang.ClassCastException: cannot assign instance of java.util.ArrayList to field SomeObject.foo of type java.util.Set in instance of SomeObject 
    at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:41) ~[spring-data-redis-1.6.4.RELEASE.jar:na] 
    at org.springframework.data.redis.cache.RedisCache$CacheValueAccessor.deserializeIfNecessary(RedisCache.java:378) ~[spring-data-redis-1.6.4.RELEASE.jar:na] 
    at org.springframework.data.redis.cache.RedisCache.get(RedisCache.java:144) ~[spring-data-redis-1.6.4.RELEASE.jar:na] 
    at org.springframework.data.redis.cache.RedisCache.get(RedisCache.java:94) ~[spring-data-redis-1.6.4.RELEASE.jar:na] 
    at org.springframework.cache.interceptor.AbstractCacheInvoker.doGet(AbstractCacheInvoker.java:68) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
    at org.springframework.cache.interceptor.CacheAspectSupport.findInCaches(CacheAspectSupport.java:466) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
    at org.springframework.cache.interceptor.CacheAspectSupport.findCachedItem(CacheAspectSupport.java:432) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:336) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:302) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE] 
    at com.sun.proxy.$Proxy175.myCachedMethod(Unknown Source) ~[na:na] 

オブジェクトをデシリアライズするときにエラーを無視して、方法が通過invokationせる春のキャッシュを設定する方法はありますか?

答えて

3

Springのコードを読んだ後に解決策が見つかりました。

キャッシュレイヤの処理は、org.springframework.cache.interceptor.CacheErrorHandlerのインスタンスで行われます。デフォルトでは、Springは全ての例外を返すorg.springframework.cache.interceptor.SimpleCacheErrorHandlerを使います。これを緩和するには、そのクラスを拡張し、キャッシュの例外をログ/無視する(キャッシュミスのように処理されます)。

@Configuration 
@EnableCaching 
public class CacheConfiguration extends CachingConfigurerSupport { 
    @Slf4j 
    private static class RelaxedCacheErrorHandler extends SimpleCacheErrorHandler { 
     @Override 
     public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) { 
      log.error("Error getting from cache.", exception); 
     } 
    } 

    @Override 
    public CacheErrorHandler errorHandler() { 
     return new RelaxedCacheErrorHandler(); 
    } 

    // More config... 
} 
関連する問題