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
相关产品推荐
相关产品推荐

