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]
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
@Jacksonizedannotation is an add-on annotation for@Builderand@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@Builderor 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, andImplis 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 usingsetterPrefix, this value is used. If you changed the name of thebuild()method using usingbuildMethodName, 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.
I found the answer.
Add lombok.config file with content:
lombok.anyConstructor.addConstructorProperties=true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With