0

In given class Base which is extended by Ext class. Serialization works perfect but issue is when trying to deserialize the serialized string back to Ext class. I want to deserialize back to Ext class including the all the Base class fields.

@Data, @NonFinal, @Value are all lombok annotations.

@Data
public class Base {

    private String foo;

    public Base( String foo) {
        this.foo = foo;
    }
}
@Value
@NonFinal
public class Ext extends Base  {

    private String bar;

    public Ext(String foo,  String bar) {
        super(foo);
        this.bar = bar;
    }

}

Method to Deserialize

    @Test
    void shouldDeserialize() throws IOException {

        ObjectMapper mapper = new ObjectMapper();
        Ext ext = new Ext("foo", "bar");

        String serializedExt = mapper.writeValueAsString(ext);
        System.out.println(serializedExt); // {"foo":"foo","bar":"bar"}
        
        // Throws err
        base = mapper.readValue(serializedExt, Ext.class);
        
    }

Error: com.fasterxml.jackson.databind.exc.InvalidDefinitionException:Cannot construct instance of ..Inhertence.Ext(no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator) at [Source: (String)"{"foo":"foo","bar":"bar"}"; line: 1, column: 2]

S K
  • 51
  • 7
  • please check this thread: https://stackoverflow.com/questions/21920367/why-when-a-constructor-is-annotated-with-jsoncreator-its-arguments-must-be-ann – Andrey B. Panfilov Dec 03 '21 at 04:38

1 Answers1

2

The error message is indicative : in your class the default constructor is not present and you haven't annotated its constructor with the JsonCreator annotation. You can deserialize your class annotating its constructor :

@Value
@NonFinal
public class Ext extends Base {

    private String bar;

    @JsonCreator
    public Ext(@JsonProperty("foo") String foo, @JsonProperty("bar") String bar) {
        super(foo);
        this.bar = bar;
    }

}
dariosicily
  • 4,239
  • 2
  • 11
  • 17
  • Thank you, however upon deserialization (`Ext(bar=bar)`), doesn't contain the Base class fields. Is it possible to also include the all the Base class field. ? Expected results to be `Ext(bar=bar, foo=foo)` – S K Dec 03 '21 at 17:28
  • 2
    @SK Actually the deserialization of `Ext` is already complete,. Only the `toString()` output of `Ext` is incomplete. Add `@ToString(callSuper=true)` to your `Èxt` class and it will work fine. – Thomas Fritsch Dec 03 '21 at 18:46
  • @SK You are welcome. As Thomas Fritsch explained in his comment you have to add the `@ToString` annotation to your class. – dariosicily Dec 04 '21 at 09:10