Builder and Jackson

624 views
Skip to first unread message

Roberto Lo Giacco

unread,
Nov 9, 2017, 4:49:05 AM11/9/17
to Project Lombok
Hi lads,

I'm trying to use Lombok and JacksonMapper together and I've found a suboptimal solution to a couple of issues I've encountered, but I believe either I'm not seeing a proper solution or there might be a couple of solutions Lombok might be able to implement.

Let me describe the issue first.

I wish to use value objects when sending data out via Jackson, so I would like to use the @Value annotation on my model objects, but at the same time, I wish to use the same objects for Jackson serialization/deserialization.
To allow easy data manipulation of my value objects I also use the @Builder and @Wither annotation on my model objects.

I know I need the @AllArgsConstructor for the @Builder, so that is added as well.

To instruct Jackson to use the builder I need to add an annotation to the generated builder class, but there is no option for that, like the onMethod = @__({ annotations } available for @Getter/@seter, etc...Something like onType would help here.

Missing that feature I've opted for letting Jackson use the default constructor (@NoArgsConstructor on my model objects), in violation of the value objects principle, but not having setters will make this default constructor pretty useless: it's still somewhat valid.


Am I missing anything? Is there another way I didn't see through which I can use Lombok with Jackson?

Martin Grajcar

unread,
Nov 9, 2017, 8:01:21 AM11/9/17
to project...@googlegroups.com
On Sun, Nov 5, 2017 at 11:08 PM, Roberto Lo Giacco <rlog...@gmail.com> wrote:
Hi lads,

I'm trying to use Lombok and JacksonMapper together and I've found a suboptimal solution to a couple of issues I've encountered, but I believe either I'm not seeing a proper solution or there might be a couple of solutions Lombok might be able to implement.

Let me describe the issue first.

I wish to use value objects when sending data out via Jackson, so I would like to use the @Value annotation on my model objects, but at the same time, I wish to use the same objects for Jackson serialization/deserialization.
To allow easy data manipulation of my value objects I also use the @Builder and @Wither annotation on my model objects.

I know I need the @AllArgsConstructor for the @Builder, so that is added as well.

To instruct Jackson to use the builder I need to add an annotation to the generated builder class, but there is no option for that, like the onMethod = @__({ annotations } available for @Getter/@seter, etc...Something like onType would help here.

AFAIK this can be done by adding a nested Builder class and annotating it. Lombok will see it and use instead of generating.
 
Missing that feature I've opted for letting Jackson use the default constructor (@NoArgsConstructor on my model objects), in violation of the value objects principle, but not having setters will make this default constructor pretty useless: it's still somewhat valid.

AFAIK @NoArgsConstructor(access=AccessLevel.PRIVATE) would be fine. It's a very tiny violation as nobody can use directly and Jackson AFAIK uses reflection.
 

Am I missing anything? Is there another way I didn't see through which I can use Lombok with Jackson?

--
You received this message because you are subscribed to the Google Groups "Project Lombok" group.
To unsubscribe from this group and stop receiving emails from it, send an email to project-lombok+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

yawkat

unread,
Nov 9, 2017, 11:40:55 AM11/9/17
to Project Lombok
Just use a (public) @AllArgsConstructor. Jackson supports deserializing such objects since 2.7.0.

Zeno Grandi

unread,
Feb 15, 2018, 8:14:24 AM2/15/18
to Project Lombok
I have successfully implemented the pattern, there is just one trick necessary: as Maartin said you need to manually add an (empty) builder class matching Lombok's, and then annotate it with @JsonPOJOBuilder.

Example:
@Value
@Builder
@JsonDeserialize(builder = MyClass.MyClassBuilder.class)
public static class MyClass {
    @NonNull private final String nonNullProperty;
    private final String nullableProperty;

    @JsonPOJOBuilder(withPrefix = "") static class MyClassBuilder {}
}


Reply all
Reply to author
Forward
0 new messages