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

Jackson反序列化报错InvalidDefinitionException:无法找到'id'属性

Jackson反序列化循环引用时的ObjectId错误

问题场景

我有如下两个Java类:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
class A {
   private B b;
   ...
   some more fields
   ...
   public B getB() {...}
   public void setB(B b){...}
}

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
class B {
   private A a;
   ...
   some more fields
   ...
   public A getA() {...}
   public void setA(A a){...}
}

尝试反序列化对象A时,出现如下错误:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Invalid Object Id definition for A: cannot find property with name 'id'

我原本以为在类级别使用该注解会自动在JSON中添加id属性,请问这个理解正确吗?该如何解决这个问题?

解答

你的理解是错误的,@JsonIdentityInfo注解不会自动为类添加id属性。当使用ObjectIdGenerators.PropertyGenerator作为生成器时,它的作用是指定类中已存在的某个属性作为对象的唯一标识,用来处理循环引用的序列化/反序列化,而非自动生成该属性。

解决方法有两种:

方法1:为类添加id属性及对应的访问方法

既然指定了property = "id",就需要在A和B类中显式添加id字段,以及对应的getter和setter方法,让Jackson能够找到这个属性作为对象标识。修改后的类示例:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
class A {
    private Long id; // 添加id属性
    private B b;
    // 其他字段...
    
    // 新增id的getter/setter
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    
    public B getB() {...}
    public void setB(B b){...}
}

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
class B {
    private Long id; // 添加id属性
    private A a;
    // 其他字段...
    
    // 新增id的getter/setter
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    
    public A getA() {...}
    public void setA(A a){...}
}

方法2:改用自动生成标识的ObjectId生成器

如果不想手动维护id属性,可以使用ObjectIdGenerators.IntSequenceGenerator(或其他自动生成器),它会自动为每个对象生成唯一的序列ID,无需类中存在对应字段。示例:

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id")
class A {
   private B b;
   ...
   some more fields
   ...
   public B getB() {...}
   public void setB(B b){...}
}

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id")
class B {
   private A a;
   ...
   some more fields
   ...
   public A getA() {...}
   public void setA(A a){...}
}

这种方式下,Jackson在序列化时会自动为每个对象添加@id字段来标识,反序列化时也会通过这个标识处理循环引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 18:40:19