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

Java Fasterxml下互相依赖JsonObject的序列化反序列化问题求解

解决方案

Jackson(即你使用的fasterxml序列化库)已经内置了处理双向循环引用的原生功能,无需自行维护ID或编写后置加载逻辑,目前有两种常用方案可按需选择:


方案1:@JsonManagedReference + @JsonBackReference

适合不需要在JSON中显式输出反向引用的场景,仅需在对应字段加注解即可:

  • 主引用侧(你需要完整序列化输出的一侧,这里是Plot类的合同列表字段)加@JsonManagedReference
  • 反向引用侧(PurchaseContract类的关联Plot字段)加@JsonBackReference

示例代码:

public class Plot {
    private Long id;
    private String plotCode;
    // 主引用侧注解
    @JsonManagedReference
    private List<PurchaseContract> purchaseContracts;
    // 省略getter、setter、构造方法
}

public class PurchaseContract {
    private Long id;
    private String contractCode;
    // 反向引用侧注解
    @JsonBackReference
    private Plot relatedPlot;
    // 省略getter、setter、构造方法
}

该方案特性:序列化时仅会输出Plot下的合同列表内容,PurchaseContract的relatedPlot字段不会写入JSON;反序列化时Jackson会自动填充反向引用的对象,不会出现重复实例或循环报错问题。


方案2:@JsonIdentityInfo

适合需要双向序列化输出的场景,比如单独序列化PurchaseContract时也需要展示关联的Plot信息,仅需在类上添加注解即可:

// 用类自带的id属性作为唯一标识
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Plot {
    private Long id;
    private String plotCode;
    private List<PurchaseContract> purchaseContracts;
    // 省略getter、setter、构造方法
}

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class PurchaseContract {
    private Long id;
    private String contractCode;
    private Plot relatedPlot;
    // 省略getter、setter、构造方法
}

如果类本身没有内置唯一ID字段,也可以使用Jackson提供的自动生成器:

@JsonIdentityInfo(generator = ObjectIdGenerators.UUIDGenerator.class)

该方案特性:序列化时首次出现的对象会输出完整内容,后续同一个对象再次被引用时仅会输出对应的唯一标识;反序列化时Jackson会自动将相同标识的引用指向同一个实例,彻底解决重复创建和循环依赖报错问题。


注意事项

两种方案均为Jackson原生功能,无需引入额外依赖,仅需添加注解即可,不会侵入业务逻辑代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 11:54:03