You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot Redis缓存清除异常:无法将Category转换为String

问题解决:Redis缓存清除时的键转换异常

问题根源

你遇到的异常是因为@CacheEvict默认会将方法参数(这里是Category实体对象)作为缓存键,但当前Redis缓存配置仅配置了值的序列化,未配置键的转换器,也未给Category重写toString()方法,导致无法将对象转换为Redis所需的String类型键。

另外,你的listAll()方法缓存的是全部分类列表,它的缓存键是默认生成的(无参数时为SimpleKey.EMPTY),而persist()方法默认用Category对象当键去清除缓存,不仅删不到正确的缓存,还触发了键转换异常,且这个转换过程在执行@CacheEvict时就会触发,和缓存是否存在无关。

解决方案

方案一:统一指定缓存键(推荐)

给@Cacheable和@CacheEvict指定同一个固定键,确保清除的是全部分类列表的缓存:

修改服务层代码:

@CacheEvict(value = CacheConstants.CACHE_NAME_PREFIX + "categories", key = "'all_categories'")
public Category persist(Category entity) {
    return repo.save(entity);
}

@Cacheable(value = CacheConstants.CACHE_NAME_PREFIX + "categories", key = "'all_categories'", unless = "#result == null")
public List<Category> listAll() {
    return repo.findAll();
}

这里用固定字符串'all_categories'作为缓存键,避免了对象转键的问题,同时确保新增分类时能正确清除全部分类的缓存。

方案二:配置Redis键序列化器(适用于需用对象作为键的场景)

如果业务需要用对象作为缓存键,可以在缓存配置中添加键的序列化器,比如使用GenericToStringSerializer:

修改CacheConfig:

@Bean
public RedisCacheConfiguration cacheConfiguration() {
    return RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofMinutes(properties.getCache().getRedisCacheEntryTtl()))
            .disableCachingNullValues()
            // 配置键的序列化器
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericToStringSerializer<>(Object.class)))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
}

但此方案不适用于当前场景,因为我们需要清除的是全部分类列表的缓存,而非单个Category的缓存。

内容的提问来源于stack exchange,提问作者Hani Bikdeli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:03:32