如何解决JPA父子关联关系下JSON响应递归嵌套的问题
解决方案
方案1:拆分DTO(最推荐,从根源避免递归)
不要使用和实体属性完全一致的DTO,拆分两个DTO类即可从结构上杜绝递归:
- 基础
PersonDTO:仅包含id、name、age三个字段,专门用来封装contacts集合内的联系人信息 - 完整
PersonDetailDTO:继承基础PersonDTO,额外新增Set<PersonDTO> contacts字段
映射时将查询到的实体转为PersonDetailDTO返回,contacts集合内的元素都是没有contacts属性的基础DTO,自然不会产生嵌套递归。
代码示例:
// 基础联系人DTO,无contacts字段 @Data public class PersonDTO { private UUID id; private String name; private int age; } // 完整详情DTO,包含联系人集合 @Data public class PersonDetailDTO extends PersonDTO { private Set<PersonDTO> contacts; }
方案2:用Jackson注解控制序列化(不想改DTO结构可直接用)
如果不愿意拆分DTO结构,直接在DTO的contacts字段上添加@JsonIgnoreProperties("contacts")注解,序列化时会自动忽略contacts集合元素里的contacts属性,不会产生嵌套:
@Data public class PersonDTO { private UUID id; private String name; private int age; @JsonIgnoreProperties("contacts") private Set<PersonDTO> contacts; }
注意不要直接用@JsonIgnore注解,该注解会直接屏蔽整个contacts字段,不符合你需要返回contacts基础信息的需求。
方案3:映射工具层面控制(使用MapStruct等映射框架时适用)
如果用MapStruct做实体到DTO的转换,写Mapper时指定contacts集合的映射规则,仅映射三个基础字段、忽略contacts属性即可:
@Mapper(componentModel = "spring") public interface PersonMapper { PersonDetailDTO toDetailDTO(Person person); // 基础DTO映射规则:忽略contacts字段 @Mapping(target = "contacts", ignore = true) PersonDTO toBaseDTO(Person person); }
内容的提问来源于stack exchange,提问作者Irinel
相关产品推荐
相关产品推荐

