Jackson Deserialization Fails because of non-default constructor created by lombok

岁酱吖の 提交于 2019-12-11 07:28:30

问题


Jackson can deserialize json for the following class in 2.6.5 but fails in 2.8.8.

Model:

public static class Parent {
    public long id;
    public List<Child> children;
}

@RequiredArgsConstructor
public static class Child {
    public long childId;

    @NonNull
    @JsonIgnore
    public Parent parent;

    public Child() { }
}

JSON:

{
  "id": 1,
  "children": [
    {
      "childId": 2
    }
  ]
}

The exception is:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "childId" (class Parent), not marked as ignorable (2 known properties: "children", "id"])

I have found that the Child constructor created by lombok is causing this error. When I get rid of the lombok annotation or if I create the constructor manually, this stops happening. Either way, it should be using the no-args Child() constructor. What is causing this issue?


回答1:


Lombok adds the annotation @ConstructorProperties({"parent"}) to the generated constructor. In Jackson 2.8.8, this causes the constructor to be treated as a "delegate creator".

A delegate creator allows Jackson to deserialize json for one type of object into another type of Java object.

In this case, because lombok generates the constructor @ConstructorProperties({"parent"}) Child(Parent parent) {...} Jackson will try to deserialize the child json as a Parent object, which could then be passed into the constructor to create a Child. It then throws the exception because childId is not a field in Parent.

One workaround is to configure the ObjectMapper used to deserialize the JSON with a custom JacksonAnnotationIntrospector so it won't interpret the constructor as a delegate creator.

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector().setConstructorPropertiesImpliesCreator(false));

Update

Version 1.16.20 of project lombok did indeed default lombok.anyConstructor.suppressConstructorProperties to true as Roel indicated might happen in his comment. That makes upgrading lombok to the latest version another fix for this issue.



来源:https://stackoverflow.com/questions/47598037/jackson-deserialization-fails-because-of-non-default-constructor-created-by-lomb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!