SpringBoot从RedisCache获取对象时出现ClassCastException问题求助
问题原因及解决方法
核心原因分析
- RedisTemplate配置存在遗漏与重复:你使用
opsForHash操作Redis哈希结构,但未配置hashValueSerializer;同时重复设置hashKeySerializer,将原本适合字符串哈希键的StringRedisSerializer覆盖为JdkSerializationRedisSerializer,既增加了不必要的复杂度,也可能导致哈希键值的序列化/反序列化逻辑不匹配。 - Otp类未显式定义
serialVersionUID:JDK序列化依赖类的版本号标识,若未显式定义serialVersionUID,类结构的细微变化(如字段增减、修饰符修改)会导致反序列化后对象类型无法匹配,触发ClassCastException。 - Redis中存在历史错误数据:若之前使用过其他序列化器(如
StringRedisSerializer)存储过数据,Redis中残留的非Otp序列化格式数据,在取出后强转时必然报错。
解决步骤
1. 修正RedisTemplate配置
调整序列化器配置,确保哈希键用字符串序列化、哈希值用JDK序列化,移除重复配置项:
@Configuration @EnableRedisRepositories public class RedisConfiguration { @Bean public JedisConnectionFactory redisConnectionFactory() { return new JedisConnectionFactory(); } @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory()); // Redis主key序列化器(对应"Otp"这个顶层key) template.setKeySerializer(new StringRedisSerializer()); // 哈希key序列化器(对应otp.getOtp()字符串键) template.setHashKeySerializer(new StringRedisSerializer()); // 哈希value序列化器(对应Otp对象) template.setHashValueSerializer(new JdkSerializationRedisSerializer()); // 普通String-Value操作的序列化器(按需保留) template.setValueSerializer(new JdkSerializationRedisSerializer()); template.afterPropertiesSet(); return template; } }
2. 给Otp类添加serialVersionUID
显式定义序列化版本号,避免类结构变化导致的反序列化异常:
@RedisHash(value = "Otp") public class Otp implements Serializable { private static final long serialVersionUID = 1L; // 你的字段、getter/setter方法 }
3. 清空Redis中的旧数据
执行Redis命令DEL Otp删除key为Otp的哈希数据,确保后续存储的是正确序列化的Otp对象。
4. 可选:改用Spring Data Redis原生Repository
利用@EnableRedisRepositories提供的自动实现能力,定义Repository接口简化操作,避免手动配置RedisTemplate的错误:
@Repository public interface OtpRepository extends CrudRepository<Otp, String> { // 自定义查询方法:根据otp值查询 Optional<Otp> findByOtp(String otp); }
使用时直接注入该Repository调用方法即可,无需手动操作RedisTemplate。
内容的提问来源于stack exchange,提问作者Seema Sharma
相关产品推荐
相关产品推荐

