5

I try to deserialize a JSON object that I receive in my API using the following code:

ObjectMapper mapper = new ObjectMapper();
ExampleDto ed = mapper.readValue(req.body(), ExampleDto.class);

My class uses Lombok to generate constructors, getters and setters, and looks like this:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExampleDto {
    private String name = "";
    private List<String> values = new LinkedList<>();
}

Both properties should be optional, and use the default value specified in the class definition if they are not provided. However, if I now try to deserialize the JSON

{name: "Foo"}

the values field is null. From my understanding, and all example code I found, values should be an empty list.

Edit: Not a duplicate, as I'm using Lombok without Optionals

skappler
  • 722
  • 1
  • 10
  • 26
  • 4
    Possible duplicate of [Implicit default values when deserializing JSON using Jackson](https://stackoverflow.com/questions/29928841/implicit-default-values-when-deserializing-json-using-jackson) – Tom Feb 10 '18 at 22:26

1 Answers1

10

@AllArgsConstructor creates the following constructor

@ConstructorProperties({"name", "values"})
ExampleDto(String name, List<String> values) {
    this.name = name;
    this.values = values;
}

The constructor is annotated with @ConstructorProperties which means a property-based creator (argument-taking constructor or factory method) is available to instantiate values from JSON object so jackson-databind uses this constructor to instantiate an object from ExampleDto class.

When the following line executes

mapper.readValue("{\"name\": \"Foo\"}", ExampleDto.class);

because there's no value for values in the provided JSON, null is passed for the second argument when the constructor is invoked.

If you remove @AllArgsConstructor annotation jackson-databind would use setter methods to initialize the object and in this case values would not be null

Mohammad Alavi
  • 594
  • 6
  • 9
  • Thank you, this solved my problem. I always hate this kind of problem. Even now that I know the issue it's quite hard to find additional information – skappler Feb 11 '18 at 10:47
  • And if we want to keep @AllArgsConstructor ?? How we can tell Jackson to not use this all args constructor ? – user2668735 Aug 14 '19 at 11:43
  • 2
    @user2668735 You can keep `@AllArgsConstructor` with `@AllArgsConstructor(onConstructor = @_(@JsonIgnore))`, and make sure to include a default constructor – John Masiello Jul 31 '20 at 07:20