Spring Boot升级3.0.5后Redis缓存跨实例反序列化失败求助
问题根源
你遇到的是Hibernate代理对象跨实例序列化/反序列化失败,核心原因:
- 默认使用JDK序列化缓存数据时,Hibernate生成的实体代理对象会绑定当前服务实例的
SessionFactory UUID; - 多实例部署场景下,每个实例的
SessionFactory UUID唯一,实例2反序列化实例1缓存的代理对象时,找不到对应UUID的SessionFactory,触发异常。
解决方案
方案1:缓存真实实体对象(最稳妥)
修改服务层代码,确保存入缓存的是真实Config实体而非Hibernate代理:
@Cacheable(value = "configCache", key = "{#root.methodName, #key}") @Override public Optional<Config> getByKey(String key) { Optional<Config> configOpt = confRepository.findByKey(key); // 强制初始化代理对象,获取真实实体 configOpt.ifPresent(Hibernate::initialize); return configOpt; }
也可以直接修改Repository查询方法,避免返回代理对象(比如用findByKey替代getReferenceByKey这类延迟加载方法)。
方案2:替换Redis序列化方式为JSON(推荐,通用型强)
放弃JDK序列化,改用Jackson JSON序列化,直接序列化对象的真实数据,不会携带Hibernate代理的SessionFactory绑定信息。修改CacheManager配置:
@Bean public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { // 配置Jackson序列化器 Jackson2JsonRedisSerializer<Object> jacksonSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = new ObjectMapper(); // 注册Hibernate模块,处理延迟加载代理的序列化 objectMapper.registerModule(new Hibernate5Module()); // 配置序列化特性:忽略未知属性、保留类型信息 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); jacksonSerializer.setObjectMapper(objectMapper); // 构建Redis缓存配置 RedisCacheConfiguration cacheConfig = RedisCacheConfiguration.defaultCacheConfig() .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jacksonSerializer)); return RedisCacheManager.builder(redisConnectionFactory) .transactionAware() .cacheDefaults(cacheConfig) .build(); }
需引入Hibernate的Jackson模块依赖:
<!-- Maven依赖 --> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-hibernate5</artifactId> </dependency>
Gradle依赖:
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5'
方案3:统一所有实例的SessionFactory UUID(不推荐,仅临时应急)
强制所有服务实例使用相同的SessionFactory UUID,在配置文件中添加:
spring: jpa: properties: hibernate: session_factory: uuid: fixed-uuid-for-all-instances
此方法会破坏Hibernate SessionFactory的实例隔离性,存在潜在风险,不建议生产环境使用。
内容的提问来源于stack exchange,提问作者ktcl
相关产品推荐
相关产品推荐

