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

Redisson升级后双向关联实体缓存序列化StackOverflow问题求助

缓存双向关联Hibernate实体的序列化问题(Redisson版本升级后)

背景

项目采用默认配置的RedissonClient与RedissonSpringCacheManager,通过@Cacheable注解缓存Hibernate双向关联实体。因项目规模限制,暂无法改用DTO缓存或修改实体关联关系。

实体代码

@Entity
public class User implements Serializable {
    @Id
    @Column(name = "user_id")
    private Long id;
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "user", cascade = CascadeType.ALL)
    private Set<Address> addresses;
}

@Entity
@Table(name = "address")
public class Address implements Serializable { 
    @Id
    private Long id;
    @ManyToOne
    @JoinColumn(name = "user_id", referencedColumnName = "user_id", nullable = false)
    private User user;
}

缓存配置

@Bean
CacheManager cacheManager(RedissonClient redissonClient) {
    Map<String,CacheConfig> config = new HashMap<>();
    config.put("users", new CacheConfig(liveTime, idleTime));
    return new RedissonSpringCacheManager(redissonClient, config);
}

缓存方法

@Cacheable(cacheNames = "users", key = "#p0", condition = "#p0 != null", unless = "#result == null")
public User findById(Long id) {
    return userRepository.findById(id);
}

问题现象

该功能在Redisson 3.17.1版本可正常运行,但升级至3.23.1版本后,调用findById方法缓存User实体时抛出序列化异常:

com.esotericsoftware.kryo.KryoException: A StackOverflow occurred. The most likely cause is that your data has a circular reference resulting in infinite recursion. Try enabling references with Kryo.setReferences(true). If your data structure is really more than 1320 levels deep then try increasing your Java stack size. Serialization trace:
addresses (com.test.User)
user (com.test.Address)
addresses (com.test.User)
user (com.test.Address)
addresses (com.test.User)
...

已尝试的方案

  • 方案1:自定义Kryo5Codec开启引用支持
    实现代码:

    public class CustomKryo5Codec extends Kryo5Codec {
        @Override
        protected Kryo createKryo(ClassLoader classLoader) {
            Kryo kryo = super.createKryo(classLoader);
            kryo.setReferences(true);
            return kryo;
        }
    }
    

    结果:实体可成功存入缓存,但读取时抛出org.hibernate.LazyInitializationException: failed to lazily initialize a collection, could not initialize proxy - no Session异常。

  • 方案2:切换为MarshallingCodec
    结果:缓存功能恢复正常,但不确定该方案是否为最优解。

请求解决办法

希望获取其他可行的优质解决方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:08:17