Spring Data JPA 如何更新递归实体并解决双向关联栈溢出问题
什么是Stack Overflow Error?
栈溢出错误是JVM运行时错误的一种,当程序的方法调用链深度超过JVM设定的最大栈容量时就会触发。你当前场景的报错是双向关联实体的无限递归调用导致的:School实体持有Student集合,每个Student实体又持有对应的School引用,在调用对象的toString、属性映射、序列化操作时,会循环读取两个对象的关联属性,方法调用无限嵌套最终撑爆栈空间。
问题根因
你的场景下触发无限递归有4个明确原因:
- Lombok的
@Data注解默认会自动生成全属性的toString、equals、hashCode方法,双向关联的两个实体会互相调用对应方法形成死循环 ModelMapper做对象映射时会递归遍历所有属性,碰到双向关联属性会无限嵌套读取- 双向关联配置错误:School类
@OneToMany注解的mappedBy属性值写的是tournee,和Student类中关联School的属性名school不匹配,会导致关联关系异常 - 若接口直接返回关联实体做JSON序列化,Jackson等序列化工具也会递归读取属性触发循环
修复方案
按优先级执行以下操作即可解决问题:
- 修正关联配置错误:把School类的
@OneToMany注解的mappedBy值改为school - 切断Lombok的递归生成:在Student类的
school属性上添加@ToString.Exclude、@EqualsAndHashCode.Exclude注解,避免自动生成的方法触发循环 - 配置ModelMapper跳过递归属性:
要么裁剪DTO结构,StudentDTO中仅保留School的id、名称等基础字段,不保留完整的School对象;要么配置ModelMapper映射规则,跳过Student类中school属性的映射
同时建议把ModelMapper注册为Spring单例Bean复用,不要每次调用都new实例,避免性能损耗 - 序列化循环处理(如果需要返回关联数据给前端):
在School类的students属性上加@JsonManagedReference,在Student类的school属性上加@JsonBackReference,JSON序列化时会自动切断循环;或者直接在不需要序列化的关联属性上加@JsonIgnore - 额外代码修正:Service层方法的参数
school Dto中间有多余空格,改为schoolDto避免编译错误
内容的提问来源于stack exchange,提问作者Otakoucht Mohamed
相关产品推荐
相关产品推荐

