Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson deserialization of a Lombok @Builder class using a mixin is not working

This is my class:

@Builder
@Value
public class A {
    int id;
    String name;
    @NonNull String lastName;
}

The Lombok @Builder will add the all args constructor.

I need to deserialise a string into a POJO object.

I created the following Jackson mixin containing all three properties:

public abstract class AMixin {
    public AMixin(@JsonProperty("name") String name,
                  @JsonProperty("id") int id,
                  @JsonProperty("lastName") String lastName) {
    }

    @JsonProperty("name")
    abstract String getName();

    @JsonProperty("id")
    abstract int getId();

    @JsonProperty("lastName")
    abstract String getLastName();

}

I deserialise like this:

public static void main(String[] args) throws Exception {


        ObjectMapper mapper = new ObjectMapper();
        mapper.addMixIn(A.class, AMixin.class);

        String ss = "{\"id\":1,\"name\":\"some name\",\"lastName\":\"some name\"}\n";
        A c = mapper.readValue(ss, A.class);
    }

but I get this error:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.bla.test.A` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"id":1,"name":"some name","lastName":"some name"}
"; line: 1, column: 2]
like image 343
Marco Dinatsoli Avatar asked Dec 05 '25 14:12

Marco Dinatsoli


2 Answers

The issue here is that Jackson expects a no-argument constructor or some other configured way of creating the object. However, because of the @Builder annotation on A, the no-argument constructor is not present, only the Lombok-generated all-argument constructor A(int id, String name, String lastName).

As of Lombok v1.18.14, the @Jacksonized annotation can be added to the class with the @Builder annotation, which automatically configures the builder to be used for Jackson deserialization.

@Jacksonized
@Builder
@Value
public class A {
    int id;
    String name;
    @NonNull String lastName;
}

The Lombok documentation for @Jacksonized describes this annotation in more detail:

The @Jacksonized annotation is an add-on annotation for @Builder and @SuperBuilder. It automatically configures the generated builder class to be used by Jackson's deserialization. It only has an effect if present at a context where there is also a @Builder or a @SuperBuilder; a warning is emitted otherwise.

[...]

In particular, the annotation does the following:

  • Configure Jackson to use the builder for deserialization using @JsonDeserialize(builder=_Foobar_._Foobar_Builder[Impl].class)) on the class (where Foobar is the name of the annotated class, and Impl is added for @SuperBuilder). (An error is emitted if such an annotation already exists.)
  • Copy Jackson-related configuration annotations (like @JsonIgnoreProperties) from the class to the builder class. This is necessary so that Jackson recognizes them when using the builder.
  • Insert @JsonPOJOBuilder(withPrefix="") on the generated builder class to override Jackson's default prefix "with". If you configured a different prefix in lombok using setterPrefix, this value is used. If you changed the name of the build() method using using buildMethodName, this is also made known to Jackson.
  • For @SuperBuilder, make the builder implementation class package-private.

Note: This issue has nothing to do with the usage of a mixin, which can be verified by moving Jackson configuration from the mixin to the class itself and observing that the issue is still present.

like image 62
M. Justin Avatar answered Dec 08 '25 08:12

M. Justin


I found the answer.

Add lombok.config file with content:

lombok.anyConstructor.addConstructorProperties=true
like image 40
Marco Dinatsoli Avatar answered Dec 08 '25 07:12

Marco Dinatsoli



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!