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

已添加@Transactional仍遇LazyInitializationException问题求助

解决JPA延迟初始化集合错误的方案

问题原因

尽管你在控制器方法上添加了@Transactional,但事务仅在控制器方法执行期间有效。当方法返回视图名称后,事务会提交、Hibernate Session随之关闭。而视图模板(如Thymeleaf)渲染时才会尝试访问KhachHang的suDungMay和suDungDichVu集合,此时已无可用Session初始化懒加载集合,因此抛出错误。

解决方案

1. 修改关联为立即加载(快速但需注意性能)

直接在KhachHang实体的@OneToMany注解中指定fetch = FetchType.EAGER,让JPA查询客户时一次性加载关联集合:

@Entity
public class KhachHang {
    // ... 其他字段
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "khachHang", fetch = FetchType.EAGER)
    private List<SuDungMay> suDungMay;
    
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "khachHang", fetch = FetchType.EAGER)
    private List<SuDungDichVu> suDungDichVu;
}

注意:如果客户数量多或关联集合数据量大,立即加载会导致查询性能下降,仅适合小规模数据场景。

2. 使用JOIN FETCH查询(推荐,性能最优)

在Repository层自定义JPQL查询,通过JOIN FETCH一次性加载客户及其关联集合,避免N+1查询,同时确保集合在事务内完成加载:

  • 第一步:修改KhachHangRepository,添加自定义查询方法
public interface KhachHangRepository extends JpaRepository<KhachHang, String> {
    @Query("SELECT k FROM KhachHang k LEFT JOIN FETCH k.suDungMay LEFT JOIN FETCH k.suDungDichVu")
    List<KhachHang> findAllWithAssociations();
}
  • 第二步:控制器调用该方法
@GetMapping(value = "/")
public String allCustomerInfo(Model model) {
    List<KhachHang> listKhachHang = khachHangRepository.findAllWithAssociations();
    model.addAttribute("listAllCustomer", listKhachHang);
    return "allcustomerinfo";
}

这种方式仅需一次查询即可获取所有需要的数据,是JPA处理关联集合的最佳实践。

3. 事务内手动初始化集合(临时解决方案)

如果不想修改Repository,可在控制器的事务范围内手动触发集合初始化,确保Session关闭前完成加载:

@GetMapping(value = "/")
@Transactional
public String allCustomerInfo(Model model) {
    List<KhachHang> listKhachHang = khachHangRepository.findAll();
    // 遍历集合触发懒加载初始化
    for(KhachHang kh : listKhachHang) {
        kh.getSuDungMay().size(); // 调用size()触发集合加载
        kh.getSuDungDichVu().size();
        // 或者使用Hibernate.initialize():
        // Hibernate.initialize(kh.getSuDungMay());
        // Hibernate.initialize(kh.getSuDungDichVu());
    }
    model.addAttribute("listAllCustomer", listKhachHang);
    return "allcustomerinfo";
}

注意:此方法会产生N+1条SQL查询(1条查客户,N条查每个客户的关联集合),性能较差,仅适合临时调试或数据量极小的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 22:16:06