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

Spring中@JsonIgnore失效引发JSON序列化无限循环问题求助

解决JSON序列化无限循环问题

针对双向ManyToMany关联导致的JSON无限循环问题,提供以下几种可行的解决方法:

方法1:使用Jackson双向关联注解

在双向关联场景下,@JsonIgnore可能因EAGER加载特性出现预期外的序列化行为,改用@JsonManagedReference和@JsonBackReference可精准控制序列化方向:

  • 在CProduct的sizes字段添加@JsonManagedReference(主动序列化的一端)
  • 在CSize的products字段添加@JsonBackReference(被忽略序列化的一端)

修改后的实体类代码:

@Entity
@Table(name = "product")
public class CProduct {
    // 其他字段保持不变
    @JsonManagedReference
    @ManyToMany(mappedBy = "products")
    private Set<CSize> sizes = new HashSet<>();
}
@Entity
@Table(name = "size")
public class CSize {
    // 其他字段保持不变
    @JsonBackReference
    @ManyToMany(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
    @JoinTable(name = "product_size", joinColumns = { @JoinColumn(name = "size_id") }, inverseJoinColumns = {
            @JoinColumn(name = "product_id") })
    private Set<CProduct> products = new HashSet<>();
}

方法2:使用@JsonIgnoreProperties指定忽略字段

在CProduct的sizes字段上直接指定忽略CSize中的products属性,序列化CProduct时会自动排除CSize里的products字段:

@Entity
@Table(name = "product")
public class CProduct {
    // 其他字段保持不变
    @ManyToMany(mappedBy = "products")
    @JsonIgnoreProperties("products")
    private Set<CSize> sizes = new HashSet<>();
}

这种方式无需修改CSize类的注解,适合快速调整序列化规则。

方法3:使用DTO(数据传输对象)分离实体与返回数据

这是最推荐的长期解决方案,通过创建独立的DTO类精确控制返回字段,完全避免实体类的序列化耦合:

  1. 创建ProductDTO和SizeDTO:
public class ProductDTO {
    private Long id;
    private String name;
    private Long price;
    private Long discount;
    private Long stock;
    private Date dateCreate;
    private boolean featured;
    private String url_img;
    private String description;
    private Set<SizeDTO> sizes;

    // 构造方法、getter/setter
}
public class SizeDTO {
    private Long id;
    private String size;

    // 构造方法、getter/setter(不包含products字段)
}
  1. 查询CProduct列表后,通过工具类(如MapStruct、ModelMapper)将实体转换为DTO再返回:
// 示例:使用ModelMapper转换
ModelMapper modelMapper = new ModelMapper();
List<ProductDTO> productDTOs = cProductRepository.findAll().stream()
    .map(product -> modelMapper.map(product, ProductDTO.class))
    .collect(Collectors.toList());
return productDTOs;

以上三种方法均可解决问题,其中DTO方式最利于后续维护和扩展,建议优先考虑。

内容的提问来源于stack exchange,提问作者Thông Hoàng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:01:36