Lombok Serialize and Deserialize @Builder Class

Learn to serialize and deserialize Lombok @Builder annotated class with Jackson library.

For demo purpose, we are using Article class have few field members. We have created this class during the Lombok @Builder tutorial.

@Builder
@Getter
@ToString
public class Article {

  private Long id;
  private String title;
  private List<String> tags;
}

1. Serializing @Builder Class

The serialization process is very simple and we do not do anything extra. It works out of the box.

1.1. Gson

Java program to serialize @Builder class using Gson.

Article article = Article.builder(1L)
  .title("Test Article")
  .tag("Test Tag")
  .build();

//With Gson
Gson gson = new Gson();
String gsonJson = gson.toJson(article);

//Prints {"id":1,"title":"Test Article","tags":["Test Tag"]}
System.out.println(gsonJson); 

1.2. Jackson

Java program to serialize @Builder class using Jackson.

Article article = Article.builder(1L)
  .title("Test Article")
  .tag("Test Tag")
  .build();

//With Jackson
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(article);

//Prints {"id":1,"title":"Test Article","tags":["Test Tag"]}
System.out.println(json); 

2. Deserializing @Builder Class

2.1. Gson

Gson works great for deserialization as well, without any extra configuration. We can use it directly.

String json = "{\"id\":1,\"title\":\"Test Title\",\"tags\":[\"Test Tag\"]}";

Gson gson = new Gson();
Article gsonArticle = gson.fromJson(json, Article.class);

//Prints Article(id=1, title=Test Title, tags=[Test Tag])
System.out.println(gsonArticle);

2.2. Jackson

By default, if we try to deserialize the Article class we will get the runtime exception InvalidDefinitionException. The Jackson is not able to find a way to construct the object in the absence of a default no-args constructor.

ObjectMapper mapper = new ObjectMapper();
String json = "{\"id\":1,\"title\":\"Test Title\",\"tags\":[\"Test Tag\"]}";
Article article = mapper.readValue(json, Article.class);
System.out.println(article);
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Cannot construct instance of `com.howtodoinjava.demo.lombok.Article` 
(no Creators, like default constructor, exist): cannot deserialize from Object value 
(no delegate- or property-based Creator)
 at [Source: (String)"{"id":1,"title":"Test Title","tags":["Test Tag"]}"; line: 1, column: 2]

2.2.1. Lombok @Jacksonized

Using @Jacksonized annotation is the simplest solution if you are using Jackson for deserialization purposes. Just annotate the @Builder class with @Jacksonized annotation and we are good for converting the JSON string to Java object.

@Builder(toBuilder = true)
@Getter
@ToString
@Jacksonized
public class Article {
    ...
}
String json = "{\"id\":1,\"title\":\"Test Title\",\"tags\":[\"Test Tag\"]}";

ObjectMapper mapper = new ObjectMapper();
Article article = mapper.readValue(json, Article.class);

//prints Article(id=1, title=Test Title, tags=[Test Tag])
System.out.println(article);

2.2.2. Jackson @JsonDeserialize and @JsonPOJOBuilder

Keep in mind that @Jacksonized is an experimental feature and may be removed in future versions. Another approach to make @Builder work with Jackson is by adding Jackson annotation which can help Jackson to figure out how to create an instance of Article class.

The two such annotations are:

@Builder
@Getter
@ToString
@JsonDeserialize(builder = Article.ArticleBuilder.class)
public class Article {
  private Long id;
  private String title;
  private List<String> tags;

  @JsonPOJOBuilder(withPrefix="")
  public static class ArticleBuilder {
  }
}
String json = "{\"id\":1,\"title\":\"Test Title\",\"tags\":[\"Test Tag\"]}";

ObjectMapper mapper = new ObjectMapper();
Article article = mapper.readValue(json, Article.class);

//Prints Article(id=1, title=Test Title, tags=[Test Tag])
System.out.println(article);

3. Conclusion

Based on the above conversation, Google Gson works best for serialization and deserialization purposes on classes annotated with Lombok @Builder. It should be the preferred approach as it works out of the box.

If using Jackson is required, we have @Jacksonized annotation that works best with very little code. In the future, if @Jacksonized is not part of Lombok then during library upgrades we can use other Jackson annotations to make deserialization work.

Happy Learning !!

Download Sourcecode

Comments are closed for this article!

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.