繁体   English   中英

带有 JPA 实体的 Spring Boot Cacheable 注释

[英]Spring boot Cacheable annotation with JPA entity

我正在尝试通过@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个解决方案。

  1. 添加可implements Serializable到 JPA 实体的实现
  2. @Cacheable注解中使用 cacheManager

我很好奇在生产中使用哪种方法。

谢谢。

我认为您的RedisTemplate实际上并未在任何地方使用。 您必须改为提供RedisCacheConfiguration (取自“Spring Boot Cache with Redis” ):

@Bean
public RedisCacheConfiguration cacheConfiguration() {
    return RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(60))
            .disableCachingNullValues()
            .serializeValuesWith(SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
}

添加注解@EnableCaching,看看效果。

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
@EnableCaching
public class RoomQueryService {
private final RoomRepository roomRepository;

@Cacheable(value = "search", key = "#code")
public Room searchRoomByCode(String code) {
    return 
  roomRepository.findByCode(code).orElseThrow(RoomNotFoundException::new);
  }
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM