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

为什么Spring Data JPA findAll()返回的对象无法访问关联映射字段

问题成因

这个异常是Hibernate懒加载机制的正常表现,你没有遗漏基础配置,触发原因如下:

  • 你给addressesList的@OneToMany关联明确指定了fetch = FetchType.LAZY,而@ManyToMany注解默认的加载策略就是LAZY,这两个关联集合都是懒加载属性,不会和User的基础字段一起查询。
  • 懒加载属性的初始化必须依赖处于开启状态的Hibernate Session上下文:userRepository.findAll()执行完成后,对应的Session就会自动关闭,后续不管是调试器读取集合属性触发toString方法,还是代码里手动调用getter方法访问关联集合,都没有可用的Session去数据库加载关联数据,就会抛出LazyInitializationException。
可用修复方案

方案1:修改关联加载策略为立即加载(仅适合小体量关联场景)

直接把关联的fetch属性改为FetchType.EAGER,查询User的时候会同步查关联数据:

// 地址关联修改为立即加载
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true)
@JsonManagedReference
private Set<Address> addressesList = new HashSet<>();

// 用户类型关联修改为立即加载
@ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.MERGE })
@JoinTable(
    name = "portal_user_user_type", 
    joinColumns = { @JoinColumn(name = "portal_user_id_fk") }, 
    inverseJoinColumns = { @JoinColumn(name = "user_type_id_fk") }
)
Set<UserType> userTypes;

注意:该方案会导致每次查询User都默认关联查地址和用户类型,数据量大、关联多的时候会有严重性能损耗,不推荐全局使用。

方案2:使用JPQL的FETCH JOIN主动加载关联(生产环境最推荐,灵活可控)

在UserRepository中自定义查询方法,用FETCH JOIN指定本次查询需要加载的关联,查询时就会一次性返回所有需要的数据,后续不依赖Session:

public interface UserRepository extends JpaRepository<User, Integer> {
    @Query("SELECT u FROM User u LEFT JOIN FETCH u.addressesList LEFT JOIN FETCH u.userTypes")
    List<User> findAllWithAssociations();
}

测试时把findAll()替换为自定义的findAllWithAssociations()即可。

方案3:测试方法加@Transactional注解(仅适合单元测试场景)

给测试方法添加@Transactional注解,整个测试方法执行期间Session会保持开启,直到方法执行结束才关闭,访问懒加载属性时可以正常初始化:

@Test
@Order(2)
@Transactional
public void RetrieveAllUsers() {
    List<User> usersList = this.userRepository.findAll();
    System.out.println(usersList.get(0).getAddressesList());
    System.out.println(usersList.get(0).getUserTypes());
    assertTrue(true);
}

注意:该方案仅适合测试场景,生产环境不要随意给查询方法加Transactional,容易引发长事务、连接占用过久等问题。

方案4:开启Open Session In View(不推荐生产环境使用)

在application.properties中添加配置:

spring.jpa.open-in-view=true

该配置会让整个请求生命周期内Session保持开启,虽然可以解决懒加载异常,但会导致长事务、数据库连接占用时间过长、性能下降等问题,生产环境不建议使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:06:04