Spring Boot JPA懒加载序列化JSON报failed to lazily initialize错误求助
问题根因
这是JPA典型的懒加载序列化异常,触发原因如下:
@OneToMany和@ManyToMany关联默认的fetch策略是LAZY(懒加载),你当前的User实体中reservations、roles两个关联字段都没有显式指定fetch策略,只会在代码第一次主动访问字段时才会发起数据库查询加载数据- 查询User对象完成后对应的数据库Session已经关闭,后续Jackson框架序列化User对象为JSON时,需要读取
reservations字段的值,此时没有可用的Session加载懒代理对象,就抛出了对应报错。此外roles字段后续也会触发相同的异常。
解决方案
方案1:接口不需要返回关联字段
如果接口不需要返回用户的预定、角色信息,直接给关联字段添加序列化忽略注解即可,改动最小性能最高:
@Entity @Data @NoArgsConstructor @AllArgsConstructor public class User { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private Long id; private String username; private String password; private Long number; private Long balance; @JsonIgnore // 序列化时忽略该字段 @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List<Reservation> reservations; @JsonIgnore // 序列化时忽略该字段 @ManyToMany private Collection<Role> roles; }
方案2:接口需要返回关联字段
如果接口确实需要返回关联的预定、角色数据,修改关联注解的fetch策略为急加载,查询用户时会同步拉取关联数据:
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER) private List<Reservation> reservations; @ManyToMany(fetch = FetchType.EAGER) private Collection<Role> roles;
方案3:多接口差异化返回场景
如果部分接口需要返回关联数据、部分不需要,不建议修改全局fetch策略,可在Repository层自定义查询语句按需加载关联字段:
// UserRepository中自定义查询方法,查询用户时同步加载预定数据 @Query("SELECT u FROM User u LEFT JOIN FETCH u.reservations WHERE u.id = :userId") Optional<User> findUserWithReservationsById(Long userId);
这种方式不会影响其他接口的查询性能,是生产环境最推荐的实现方式。
内容的提问来源于stack exchange,提问作者Mile Stanislavov
相关产品推荐
相关产品推荐

