首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Spring缓存缓存Java 8的可选性

使用Spring缓存缓存Java 8的可选性
EN

Stack Overflow用户
提问于 2016-01-17 22:03:11
回答 3查看 21.1K关注 0票数 12

我有一个方法:

代码语言:javascript
复制
@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类型的对象

EN

回答 3

Stack Overflow用户

发布于 2018-11-06 12:00:40

只需在DTO中实现可序列化的接口即可。

代码语言:javascript
复制
@Document(collection = "document_name")
public class Document implements Serializable {

    private static final long serialVersionUID = 7156526077883281623L;
票数 14
EN

Stack Overflow用户

发布于 2016-01-17 23:36:02

Spring支持可选缓存。问题是您的Redis序列化程序(可能是JdkSerializationRedisSerializer)。它使用基于Java的序列化,这要求类是可序列化的。您可以通过将RedisCacheManager配置为使用另一个没有此限制的序列化程序来解决这一问题。例如,您可以使用Kryo (com.esotericsoftware:kryo:3.0.3):

代码语言:javascript
复制
@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缓存的方式相同。

票数 8
EN

Stack Overflow用户

发布于 2016-12-06 07:17:04

因为您的序列化对象没有实现RedisSerializer,或者您可以扩展类JdkSerializationRedisSerializer,该类具有实现RedisSerializer。

示例代码:

代码语言:javascript
复制
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;

....
}

更多细节和原则,请访问我的博客

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34844290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档