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

Postman发送Get请求返回重复结果 Spring Boot JPA实体序列化异常

你遇到的问题核心是Jackson序列化双向关联时的无限递归,并非数据库查询返回了重复数据:Chemistry和ChemistryAnswer为双向一对一关联,序列化返回JSON时,Jackson会先序列化Chemistry的answer属性,接着序列化ChemistryAnswer的question属性,又回到Chemistry对象循环往复,最终呈现出大量重复嵌套的相同内容。

解决方案

以下三种方案按需选择即可:

方案1:使用关联注解打断循环(推荐)

这是双向关联序列化的标准解决方案,在关系的维护方加@JsonManagedReference,被维护方加@JsonBackReference:
修改Chemistry类的answer属性:

@OneToOne(mappedBy = "question",cascade = CascadeType.ALL)
@JsonManagedReference
private ChemistryAnswer answer = new ChemistryAnswer();

修改ChemistryAnswer类的question属性:

@OneToOne
@JoinColumn(name = "question_id")
@JsonBackReference
private Chemistry question;

序列化时只会返回Chemistry下的answer内容,不会返回answer下的question字段,完美打断循环。

方案2:直接忽略循环字段

如果不需要在返回结果中展示answer关联的question信息,可以直接给ChemistryAnswer的question属性加@JsonIgnore注解:

@OneToOne
@JoinColumn(name = "question_id")
@JsonIgnore
private Chemistry question;

这个方案实现最简单,适合不需要反向关联序列化的场景。

方案3:用对象唯一标识避免重复序列化

如果需要保留双向关联的序列化,可以给两个实体类都加@JsonIdentityInfo注解,Jackson会用对象ID代替重复出现的同一对象:
给Chemistry类加类注解:

@Entity
@Table(name = "Chemistry")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Chemistry {
    // 原有代码不变
}

给ChemistryAnswer类加类注解:

@Entity
@Table(name = "Chemistryanswer")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class ChemistryAnswer {
    // 原有代码不变
}

这个方案序列化后如果同一对象重复出现,只会输出一次完整内容,后续只输出ID值,避免了无限递归同时保留了关联关系。

额外注意事项
  • 你在Chemistry类中直接初始化private ChemistryAnswer answer = new ChemistryAnswer(),如果查询到的Chemistry没有关联的answer记录,序列化时会返回空的ChemistryAnswer对象而不是null,如有需要可以去掉初始化逻辑。
  • 你同时引入了spring-boot-starter-data-rest和自定义RestController,注意不要出现路径冲突,目前配置的路径没有冲突无需修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 23:24:02