Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lombok + Jackson immutables

After updating my project to Spring Boot 1.5.10 Lombok stopped working correctly with Jackson. I mean immutable DTOs creation, when field names in my objects are not same as fields in json request:

@Value
@Builder
public class MyImmutableDto implements Serializable {

    @JsonProperty("other-field-1-name")
    private final BigDecimal myField1;

    @JsonProperty("other-field-2-name")
    private final String myField2;

    and a lot of fields there...
}

So, after updating Spring Boot to 1.5.10 this code isn't working, and I need to configure lombok like that:

lombok.anyConstructor.addConstructorProperties = true

Does anyone know any other way to create such objects with jackson + lombok without this lombok fix? Instead of this fix I can use following code: @JsonPOJOBuilder and @JsonDeserialize(builder = MyDto.MyDtoBuilder.class):

@Value
@Builder
@JsonDeserialize(builder = MyDto.MyDtoBuilder.class)
public class MyDto implements Serializable {

    // @JsonProperty("other-field-1-name")    // not working
    private final BigDecimal myField1;

    private final String myField2;
    private final String myField3;
    and a lot of fields there...

    @JsonPOJOBuilder(withPrefix = "")
    public static final class MyDtoBuilder {
    }
}

But it is not working with @JsonProperty("other-field-1-name"). Ofc, it can be done by simple @JsonCreator, but maybe there is some way to use it with lombok using some constructor/jackson annotations?

like image 208
Rands7 Avatar asked Feb 06 '18 13:02

Rands7


People also ask

Does Lombok work with Jackson?

ConstructorProperties annotations. Lombok will automatically add this annotation to the constructors it generates. This project is compatible with Jackson 2.4 - 2.6.

Does Jackson require no args constructor?

By default, Jackson recreates data objects by using no-arg constructors. This is inconvenient in some cases, such as when a class has non-default constructors and users have to write no-arg ones just to satisfy Jackson's requirements.

What does @jacksonized annotation do?

Overview. 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 ...

Which constructor does Jackson use?

Jackson uses default (no argument) constructor to create object and then sets value using setters. so you only need @NoArgsConstructor and @Setter.


1 Answers

So this is not the exact same case, but this works for my problem. I need the @JsonDeserialize annotation on the builder, putting it there on the builder explicitly solves the problem (at the cost of boilerplate code). At least I don't need to type out the rest of the builder.

@Value
@Builder
@JsonDeserialize(builder = ProductPrice.ProductPriceBuilder.class)
public class ProductPrice {

    @JsonSerialize(using = MoneySerializer.class)
    @JsonDeserialize(using = MoneyDeserializer.class)
    Money price;

    Duration rentalLength;

    Period recurrence;

    @JsonPOJOBuilder(withPrefix = "")
    public static class ProductPriceBuilder{
        @JsonDeserialize(using = MoneyDeserializer.class)
        public ProductPrice.ProductPriceBuilder price(Money price) {
            this.price = price;
            return this;
        }  
    }
}
like image 89
simon Avatar answered Oct 06 '22 02:10

simon