SpringBoot中OneToMany/ManyToOne循环引用致栈溢出问题求助
问题原因分析
你遇到的StackOverflowException确实是双向关联导致的循环递归引发的,但不止JSON序列化这一种场景:
- Lombok的
@Data注解会自动生成toString()、equals()和hashCode()方法,这些方法会包含关联实体:Region的toString()会输出cities列表,每个City的toString()又会反向输出关联的Region,无限递归直接触发栈溢出。 - 即使给
Region的cities加了@JsonIgnore,如果业务代码中调用了实体的toString()(比如日志打印),依然会触发这个问题。
解决方案
方案1:修复Lombok自动生成的方法(核心解决toString/equals递归)
给双向关联的字段添加排除注解,避免Lombok在生成方法时包含关联对象:
修改后的Region类
@Data @Entity @Table(name = "region") public class Region { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name = "name", nullable = false) private String name; @ManyToOne @JoinColumn(name = "id_country", nullable = false) private Country country; @JsonIgnore @ToString.Exclude @EqualsAndHashCode.Exclude @OneToMany(mappedBy = "region") private List<City> cities; }
修改后的City类
@Data @Entity @Table(name = "city") public class City { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name = "name", nullable = false) private String name; @ToString.Exclude @EqualsAndHashCode.Exclude @ManyToOne @JoinColumn(name = "id_region", nullable = false) private Region region; }
方案2:优雅处理JSON序列化的双向引用(针对接口返回场景)
如果是接口返回Region数据时触发的序列化递归,可以用Jackson的双向引用注解替代@JsonIgnore,既保留序列化主动关联,又避免递归:
@Data @Entity @Table(name = "region") public class Region { // ... 其他字段 @JsonManagedReference // 主动引用,会被序列化 @OneToMany(mappedBy = "region") private List<City> cities; } @Data @Entity @Table(name = "city") public class City { // ... 其他字段 @JsonBackReference // 反向引用,不会被序列化 @ManyToOne @JoinColumn(name = "id_region", nullable = false) private Region region; }
方案3:启用懒加载减少不必要的关联加载
在@OneToMany注解上添加懒加载配置,默认不加载cities列表,只有主动调用时才触发关联查询,降低递归触发概率:
@JsonIgnore @ToString.Exclude @EqualsAndHashCode.Exclude @OneToMany(mappedBy = "region", fetch = FetchType.LAZY) private List<City> cities;
内容的提问来源于stack exchange,提问作者Moiap13
相关产品推荐
相关产品推荐

