为什么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
相关产品推荐
相关产品推荐

