迁移Redis序列化DTO包路径后,指定serialVersionUID仍报类找不到错误
解决FstCodec序列化后类包名迁移的反序列化问题
这个问题本质是FST序列化框架的特性导致的:它在序列化对象时会完整记录类的全限定类名(包含包路径),所以当你把db.data.coins.CoinDTO迁移到dto.CoinDTO后,反序列化时FST依然会尝试加载旧包名下的类,自然抛出类找不到的异常。而且这里serialVersionUID起不到作用,因为FST默认不依赖Java序列化的UID机制,它有自己独立的序列化逻辑。
下面给你两个不需要转JSON(避免双重序列化)的解决方案:
方案1:自定义FST配置添加类名映射
你可以给Redisson的FstCodec配置类名映射,告诉FST“旧的全限定类名对应新的类”,具体代码如下:
// 初始化FST配置并注册类名映射 FSTConfiguration fstConfig = FSTConfiguration.createDefaultConfiguration(); // 旧类全限定名 -> 新类Class对象 fstConfig.registerCrossPlatformClassMapping( "db.data.coins.CoinDTO", dto.CoinDTO.class ); // 使用自定义配置创建FstCodec Codec customCodec = new FstCodec(fstConfig); // 配置RedissonClient时使用这个自定义Codec Config redissonConfig = Config.fromYAML("your-redisson-config.yaml"); // 或者fromJSON redissonConfig.setCodec(customCodec); RedissonClient redisson = Redisson.create(redissonConfig);
这个映射会让FST在反序列化时,自动将旧类名关联到新类,无需修改Redis中已存储的数据,直接就能读取。
方案2:给新类添加FST别名注解
如果不想手动配置FST的类映射,也可以在新的CoinDTO类上添加@FstAlias注解,指定旧的全限定类名:
package dto; import java.io.Serializable; import java.sql.Timestamp; import org.nustaq.serialization.annotations.FstAlias; @FstAlias("db.data.coins.CoinDTO") // 指定旧的全限定类名 public class CoinDTO implements Serializable { static final long serialVersionUID = 1L; private int id; private double amount; private Timestamp timestamp; // Getters and setters }
这样FST在反序列化时,遇到旧的类名会自动匹配到带有这个注解的新类,同样能完成反序列化操作。
这两个方案都能完美解决包名迁移后的反序列化问题,而且完全避免了双重序列化的额外开销。
内容的提问来源于stack exchange,提问作者Roie Beck




