我有一个方法:
@Cacheable(key = "#jobId")
public Optional<JobInfo> getJobById(String jobId) {
log.info("Querying for job " + jobId);
counterService.increment("queryJobById");
Job job = jobsRepository.findOne(jobId);
if (job != null) {
return Optional.of(createDTOFromJob(job));
}
return Optional.empty();
}当我试图检索缓存的项时,我将得到以下异常:
2016-01-1800:01:10 ERROR trace=,span= http-nio-8021-exec-2 dispatcherServlet:182 - Servlet.service()用于servlet dispatcherServlet上下文中的路径[]抛出异常[请求处理失败;嵌套异常为trace=不能序列化;嵌套异常是org.springframework.core.serializer.support.SerializationFailedException:未能使用DefaultSerializer序列化对象;嵌套异常是java.lang.IllegalArgumentException: DefaultSerializer需要一个可序列化的有效负载,但是接收到一个java.util.Optional类型的对象]和根原因java.lang.IllegalArgumentException: DefaultSerializer需要一个可序列化的有效负载,但是接收到一个java.util.Optional类型的对象
发布于 2018-11-06 12:00:40
只需在DTO中实现可序列化的接口即可。
@Document(collection = "document_name")
public class Document implements Serializable {
private static final long serialVersionUID = 7156526077883281623L;发布于 2016-01-17 23:36:02
Spring支持可选缓存。问题是您的Redis序列化程序(可能是JdkSerializationRedisSerializer)。它使用基于Java的序列化,这要求类是可序列化的。您可以通过将RedisCacheManager配置为使用另一个没有此限制的序列化程序来解决这一问题。例如,您可以使用Kryo (com.esotericsoftware:kryo:3.0.3):
@Bean
RedisCacheManager redisCacheManager (RedisTemplate<Object, Object> redisOperations) {
// redisOperations will be injected if it is configured as a bean or create it: new RedisTemplate()...
redisOperations.setDefaultSerializer(new RedisSerializer<Object>() {
//use a pool because kryo instances are not thread safe
KryoPool kryoPool = new KryoPool.Builder(Kryo::new).build();
@Override
public byte[] serialize(Object o) throws SerializationException {
ByteBufferOutput output = new ByteBufferOutput();
Kryo kryo = kryoPool.borrow();
try {
kryo.writeClassAndObject(output, o);
} finally {
kryoPool.release(kryo);
output.close();
}
return output.toBytes();
}
@Override
public Object deserialize(byte[] bytes) throws SerializationException {
if(bytes.length == 0) return null;
Kryo kryo = kryoPool.borrow();
Object o;
try {
o = kryo.readClassAndObject(new ByteBufferInput(bytes));
} finally {
kryoPool.release(kryo);
}
return o;
}
});
RedisCacheManager redisCacheManager = new RedisCacheManager(redisOperations);
redisCacheManager.setCachePrefix(new DefaultRedisCachePrefix("app"));
redisCacheManager.setTransactionAware(true);
return redisCacheManager;
}请注意,这只是一个例子,我没有测试这个imeplementation。但我在生产中使用Kryo序列化程序的方式与Spring进行redis缓存的方式相同。
发布于 2016-12-06 07:17:04
因为您的序列化对象没有实现RedisSerializer,或者您可以扩展类JdkSerializationRedisSerializer,该类具有实现RedisSerializer。
示例代码:
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
public class YourDTOObject extends JdkSerializationRedisSerializer implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
....
}更多细节和原则,请访问我的博客
https://stackoverflow.com/questions/34844290
复制相似问题