Lombok builder pattern with jackson JsonProperty
Asked Answered
O

4

20

I have constructed a Java Object using lombok with builder pattern. But, I am getting the following exception when trying to deserialize a Java object using Jackson. This occurs for fields which has @JsonProperty annotation.

Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "user_name" (class User$UserBuilder), not marked as ignorable (2 known properties: "userName", "userId"])
at [Source: (String)"{"userId":1,"user_name":"username"}"; line: 1, column: 26] (through reference chain: User$UserBuilder["user_name"])

Code Used :

public class TestJson {
    public static void main(String args[]) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();

        User user = User.builder()
                .userName("username")
                .userId(1)
                .build();
        System.out.println(user);
        String string = objectMapper.writeValueAsString(user);
        System.out.println(string);
        user = objectMapper.readValue(string, User.class);
        System.out.println(user);
    }
}


@JsonDeserialize(builder = User.UserBuilder.class)
@Getter
@ToString
@Builder(toBuilder = true)
class User {
    @JsonProperty("user_name")
    @NonNull
    private String userName;

    @JsonProperty
    private int userId;

    @JsonPOJOBuilder(withPrefix = "")
    public static class UserBuilder {

    }
}

Kindly help me solve this issue.

Thanks.

Olwena answered 1/8, 2018 at 11:1 Comment(1)
The flip side of this is when you want Jackson to ignore extra keys in the JSON: @JsonIgnoreProperties(ignoreUnknown = true)Eunuchize
B
23

You get this error because Jackson doesn't know how to map user_name to any of your UserBuilder fields.

You need @JsonProperty("user_name") on the userName field of UserBuilder too, like that:

@JsonPOJOBuilder(withPrefix = "")
public static class UserBuilder {

    @JsonProperty("user_name")
    @NonNull
    private String userName;
}
Birdella answered 1/8, 2018 at 11:59 Comment(0)
B
9

As of Lombok v1.18.16, you should be able to use the @Jacksonized annotation.

@Data
@Jacksonized
@Builder
public class Pojo {

    @JsonProperty("package")
    String pkg;
}
Blazer answered 29/1, 2021 at 1:18 Comment(0)
A
6

Your mapper need to have a means of creating User class.

You could use constructor:

@NoArgsConstructor
@AllArgsConstructor
@Getter
@ToString
@Builder
class User {
  @JsonProperty("user_name")
  @NonNull
  private String userName;

  private int userId;
}

... or point it to builder as per Tomasz Linkowski's answer

Azide answered 1/8, 2018 at 12:25 Comment(1)
For me, the most suitable format was using builder pattern. I didn't wanted to use a constructor.Olwena
B
1

try update version

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
        <version>1.18.22</version>
    </dependency>
Bulbar answered 22/12, 2021 at 17:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.