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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 15:33:09