Immutable Lombok annotated class with Jackson Immutable Lombok annotated class with Jackson json json

Immutable Lombok annotated class with Jackson


add ConstructorProperties:

  • Create a lombok.config file in an appropriate location with the line:lombok.anyConstructor.addConstructorProperties = true
  • Add lombok @Value annotation to your class to make it immutable

Then serialization and deserialization by Jackson works as expected.

This method:

Edit: 2020-08-16

  • Note: Using @Builder with @Value causes this solution to fail. (Thanks to comment from @guilherme-blanco below.)However, if you also add e.g. @AllArgsConstructor it does still work as expected.

Edit: 2021-08-19

  • Note: When you add or change a lombok.config file the change is not picked up unless you do a rebuild (clean then build). I have been caught out by this a few times.
  • @Jacksonized annotation solution is another method to achieve the desired outcome for the specific classes annotated. However, I personally prefer not to need to remember to annotate every class used for deserialization. Using lombok.config removes this overhead.


As of 15 October 2020 (Lombok v1.18.16), you should simply be able to use the @Jacksonized annotation.

@Jacksonized @Builder@JsonIgnoreProperties(ignoreUnknown = true)public class JacksonExample {  private List<Foo> foos;}

As described in the linked documentation, this annotation:

  • configures Jackson to use the builder for deserialisation,
  • copies field-specific configuration down from the annotated class to the generated builder (e.g. @JsonIgnoreProperties), and
  • aligns the Jackson prefix used on builder methods (e.g. builder().withField(field) vs builder.field(field) to the one configured in Lombok.


You can use Lombok's @Builder annotation to generate a builder for your immutable POJO class.But making the Lombok-generated builder usable by Jackson's deserialization is somewhat tricky.

Example:

An immutable POJO class:

@Data@Builder(builderClassName = "PointBuilder")@JsonDeserialize(builder = Point.PointBuilder.class)public class Point {    private final int x;    private final int y;    @JsonPOJOBuilder(withPrefix = "")    public static class PointBuilder {        // Lombok will add constructor, setters, build method    }}

POJO outline

Here is a JUnit test to verify the serialization/deserialization:

public class PointTest extends Assert {    private ObjectMapper objectMapper = new ObjectMapper();    @Test    public void testSerialize() throws IOException {        Point point = new Point(10, 20);        String json = objectMapper.writeValueAsString(point);        assertEquals("{\"x\":10,\"y\":20}", json);    }    @Test    public void testDeserialize() throws IOException {        String json = "{\"x\":10,\"y\":20}";        Point point = objectMapper.readValue(json, Point.class);        assertEquals(new Point(10, 20), point);    }}