首页 > 解决方案 > 使用 Jackson ObjectMapper 反序列化 JSON 对象双向一对多

问题描述

我正在尝试反序列化一个 JSON 对象,例如

{ 
  "name":"aaa",
  "children": [ 
    {"name":"bbb"}
  ]
}

进入子对象引用父对象的Java对象,例如:

public class Parent {
  public String name;
  public List<Child> children;
}
public class Child {
  public String name;
  public Parent parent;
}

// ...
new ObjectMapper().readValue(<JSON>, Parent.class);

当像这样反序列化它时,Child#parent不会指向父对象。我在进行在线研究时阅读了两种方法,但似乎都不起作用。

1.在类中添加构造函数argChild设置父对象

public class Child {
  public String name;
  public Parent parent;
  public Child(Parent parent) {
    this.parent = parent;
  }
}

执行此操作时出现错误:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
  Cannot construct instance of `Child` (no Creators, like default construct, exist): 
  cannot deserialize from Object value (no delegate- or property-based Creator)
  at [Source: (String)"{"name":"aaa","children":[{"name":"bbb"}]}"; line: 1, column: 27] 
  (through reference chain: Parent["children"]->java.util.ArrayList[0])

2. 使用@JsonBackReference@JsonManagedReference注解

public class Parent {
  public String name;
  @JsonBackReference
  public List<Child> children;
}
public class Child {
  public String name;
  @JsonManagedReference
  public Parent parent;
}

这失败了:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
  Cannot handle managed/back reference 'defaultReference':
  back reference type (java.util.List) not compatible with managed type (Child)
  at [Source: (String)"{"name":"aaa","children":[{"name":"bbb"}]}"; line: 1, column: 1]

JavaDoc@JsonBackReference说它不能应用于集合,所以它显然不起作用,但我想知道为什么网上有这么多例子将它应用于集合。

问题 当反序列化对象图时,如何实现子对象自动设置其父/所有者对象。我实际上更愿意以某种方式让第一种方法以某种方式工作,因为它不会污染需要使用特定于框架的注释来污染类。

标签: javajsonjackson-databind

解决方案


关于您的第二种方法,您必须更改注释的一侧。

public class Parent {
  public String name;

  @JsonManagedReference
  public List<Child> children;
}

public class Child {
  public String name;

  @JsonBackReference
  public Parent parent;
}

推荐阅读