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

Hazelcast+Hibernate+Spring Boot集成遇懒加载无Session错误求助

解决Hazelcast 5.3 + Hibernate 5.6 + Spring Boot 2.7 集成时@Cacheable方法的LazyInitializationException问题

问题根源

你的问题出在自定义CacheManager破坏了Spring Boot默认的缓存与Hibernate会话管理的整合逻辑。手动创建HazelcastCacheManager后,Spring Boot自动配置中针对Hibernate实体缓存的会话绑定机制被覆盖,导致从Hazelcast缓存取出的Hibernate代理实体(带懒加载关联)无法获取有效Session初始化关联数据,最终抛出LazyInitializationException。


解决方案

方案1:移除自定义CacheManager,依赖Spring Boot自动配置

Spring Boot会自动检测Config或HazelcastInstance Bean,并创建适配Hibernate上下文的HazelcastCacheManager,无需手动定义。修改配置类如下:

@Configuration
public class HazelCastConfiguration {

    @Bean
    public Config hazelcastConfig() {
        Config config = new Config();

        config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(true);
        config.setClassLoader(Thread.currentThread().getContextClassLoader());
        
        final UserCodeDeploymentConfig distCLConfig = config.getUserCodeDeploymentConfig();
        distCLConfig.setEnabled(true)
                .setClassCacheMode(UserCodeDeploymentConfig.ClassCacheMode.ETERNAL)
                .setProviderMode(UserCodeDeploymentConfig.ProviderMode.LOCAL_CLASSES_ONLY);

        // 添加业务用到的缓存配置,包括@Cacheable中指定的缓存名称
        config.addMapConfig(rajouterConfig("produits",5000,0));
        config.addMapConfig(rajouterConfig("CACHE_MANAGER", 5000, 0));
        
        return config;
    }
    
    private MapConfig rajouterConfig(String nomCache, int taille, int tempsDeVie){
        return new MapConfig()
                .setName(nomCache)
                .setTimeToLiveSeconds(tempsDeVie)
                .setEvictionConfig(new EvictionConfig()
                        .setSize(taille)
                        .setMaxSizePolicy(MaxSizePolicy.PER_NODE)
                        .setEvictionPolicy(EvictionPolicy.LRU));
    }

    // 可选:如需自定义HazelcastInstance创建逻辑则保留,否则Spring Boot会自动生成
    @Bean
    public HazelcastInstance hazelcastInstance() {
        return Hazelcast.newHazelcastInstance(hazelcastConfig());
    }

    // 移除自定义的cacheManager Bean!
}

方案2:若必须自定义CacheManager,配置Hazelcast序列化策略

如果一定要手动创建HazelcastCacheManager,需配置能处理Hibernate代理的序列化器:

  1. 引入hazelcast-hibernate5依赖:
<dependency>
    <groupId>com.hazelcast</groupId>
    <artifactId>hazelcast-hibernate5</artifactId>
    <version>5.3.0</version>
</dependency>
  1. 在hazelcastConfig()方法中添加序列化配置:
config.getSerializationConfig()
        .addSerializerConfig(new SerializerConfig()
                .setTypeClass(org.hibernate.proxy.HibernateProxy.class)
                .setClass(com.hazelcast.hibernate.serialization.Hibernate4CacheSerializer.class));

方案3:避免缓存Hibernate代理实体

直接缓存DTO而非Hibernate实体,或在方法返回前初始化所有懒加载关联:

  • 在recupererParModele方法中,调用数据库查询后,用Hibernate.initialize(entity.getLazyAssociation())手动初始化懒加载属性
  • 将查询结果转换为DTO对象,缓存DTO而非实体类,彻底规避Hibernate代理问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 04:07:37