【发布时间】:2021-10-28 10:30:44
【问题描述】:
我正在尝试通过@Cacheable 注解将jpa 实体缓存到redis。
[RedisConfig.class]
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(host, port);
}
@Bean
public RedisTemplate<?, ?> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}
}
[服务层]
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class RoomQueryService {
private final RoomRepository roomRepository;
@Cacheable(value = "search", key = "#code")
public Room searchRoomByCode(String code) {
return roomRepository.findByCode(code).orElseThrow(RoomNotFoundException::new);
}
}
当执行上面的代码时,它会抛出下面的错误。
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires a Serializable payload but received an object of type [slido.slidoclone.room.domain.Room]] with root cause
可能是因为 DefaultSerializer 无法序列化 jpa 实体类造成的。
所以我在 RedisConfig 中添加了以下 2 行代码。
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
但它会抛出同样的错误。
搜索了一下,找到了2个解决方案。
- 将
implements Serializable添加到JPA 实体 - 在
@Cacheable注解中使用cacheManager
我很好奇生产中使用了哪种方法。
谢谢。
【问题讨论】:
-
大约 1. 我会“坚持规范”(在任何环境中):“如果一个实体实例将作为一个分离的对象按值传递(例如,通过远程接口),实体类必须实现 Serializable 接口。” baeldung.com/jpa-entities-serializable -> download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/…
标签: java spring spring-boot jpa