InvalidDefinitionException: Invalid Object Id definition for "class": cannot find property with name 'id'

70 Views Asked by At

I have a 2 Java classes that look like this:

@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){...}
}

Trying to deserialize object A, I get this error:

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

I thought that using the annotation on the class level adds the id property to the Json. Is it correct? How can it be solved?

2

There are 2 best solutions below

1
Techies On

Using generator = ObjectIdGenerators.PropertyGenerator.class indicates that you want to used either a field or a getter method as "identifier".

Using property = "id" show that you want the field id used as "identifier", which is redondant, according to javadoc, because "id" is the default value when not written in the annation property field.

So you can just write @JsonIdentityInfo(ObjectIdGenerators.PropertyGenerator.class)

Now, about your error, you HAVE to provide the id field in your class. The annotation does not create code, it is only metadata on code(if you think about lombok, forget it, it is stupid library).

Annotation is processed on runtime via introspection by jackson so that it know how to work with your class (it uses a PropertyGenerator, and default field name is 'id')

1
user16076953 On

I used ObjectIdGenerators.IntSequenceGenerator.class instead of ObjectIdGenerators.PropertyGenerator.class and it seems OK. But now that I added this, I'm facing a different issue:

There are 2 classes inheriting from class A:

@JsonTypeInfo(  
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,  
    property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = D.class, name = "d"),
    @JsonSubTypes.Type(value = E.class, name = "e")
})
Class A{...}


@JsonTypeName(d)   
Class D {
   ...
}

@JsonTypeName(e)   
Class E {
   ...
}

I added the ObjectIdGenerators.IntSequenceGenerator.class (to solve the circular dependency in serialization) above each one of the subclasses. And now I get:

Missing type id when trying to resolve subtype of A: missing type id property 'type'

It happens because now, instead of seeing the full object in the JSON, only its id exists in there. So in the deserialization we have an object of type A (which can be either D or E) without a "type" property (it's only a number, let's say 1) and the deserializer doesn't know which object it is: D or E. How can it be solved?