Java 如何使用 Jackson 的 @JsonIdentityInfo 进行有向图的反序列化?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24890447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 15:23:43  来源:igfitidea点击:

How To Use Hymanson's @JsonIdentityInfo for Deserialization of directed Graphs?

javajsonserializationHymansondirected-graph

提问by MalteJ

I want to use Hymanson 2.3.3 for Deserialization/Serialization of directed graphs. The structure I came up with is roughly the following:

我想使用 Hymanson 2.3.3 进行有向图的反序列化/序列化。我想出的结构大致如下:

public Class Graph {
    private final Set<Node> nodes;
    public Graph(Set<Node> nodes) { ... }
    public Set<Node> getNodes() { ... }
}

@JsonIdentityInfo(
        generator = ObjectIdGenerators.PropertyGenerator.class,
        property = "name")
public Class Node {
    private final String name;
    private final Set<Edge> edges;
    public Node(String name, Set<Edge> edges) { ... }
    public String getName() { ... }
    public Set<Edge> getEdges() { ... }
}

@JsonIdentityInfo(
        generator = ObjectIdGenerators.PropertyGenerator.class,
        property = "name")
public Class Edge {
    private final String name;
    private final Node successor;
    public Edge(String name, Node successor) { ... }
    public String getName() { ... }
    public Node getSuccessor() { ... }
}

And I expect to have this JSON-Structure:

我希望有这个 JSON 结构:

{
  "graph": [{
    "name": "A",
    "edges": [{
      "name": "0",
      "successor": "B"
    }, {
      "name": "1",
      "successor": "A"
    }]
  }, {
    "name": "B",
    "edges": [{
      "name": "0",
      "successor": "A"
    }, {
      "name": "1",
      "successor": "B"
    }]
  }]
}

But I get the following error while deserialization (even with annotation @JsonProperty("name")at the Getters):

但是在反序列化时出现以下错误(即使@JsonProperty("name")在 Getters 中有注释):

com.fasterxml.Hymanson.databind.JsonMappingException: Invalid Object Id definition for some.package.graph.Node: can not find property with name 'name'

com.fasterxml.Hymanson.databind.JsonMappingException: Invalid Object Id definition for some.package.graph.Node: can not find property with name 'name'

I have found some solutions for Hymanson 1.6 with Back-Reference Annotations, but I'd like to use the new Hymanson 2.x Annotation, as it was advertised so much in the API Update from 1.9 to 2.0 of Hymanson.

我找到了一些带有反向引用注释的 Hymanson 1.6 解决方案,但我想使用新的 Hymanson 2.x Annotation,因为它在 Hymanson 1.9 到 2.0 的 API 更新中做了很多宣传。

What point am I missing here? Thanks for constructive answers in advance.

我在这里错过了什么?感谢您提前提供建设性的答案。

EDIT

编辑

(Removed my answer from here to the Answer section)

(将我的答案从这里移到答案部分)

采纳答案by MalteJ

I got kind of blind of staring too long at it. Here's what's gone wrong:

我有点盲目地盯着它看太久。这是出了什么问题:

The Serialization actually worked as intended. What didn't work was the Deserialization, because Hymanson wasn't able to instantiate my Node-Object. I simply forgot to annotate the parameters of the constructor methods correctly.

序列化实际上按预期工作。不起作用的是反序列化,因为Hyman逊无法实例化我的节点对象。我只是忘记正确注释构造函数方法的参数。

I was now facing another problem. The generated JSON now looked like this:

我现在面临另一个问题。生成的 JSON 现在看起来像这样:

"graph": {
  "nodes": [{
    "name": "B",
    "edges": [{
      "label": "1",
      "successor": "B"
    }, {
      "label": "0",
      "successor": {
        "name": "A",
        "edges": [{
          "label": "1",
          "successor": "A"
        }, {
          "label": "0",
          "successor": "B"
        }]
      }
    }]
  }, "A"]
}

So far so good. But during mapping, Hymanson confronts me with this Error:

到现在为止还挺好。但是在映射过程中,Hymanson 向我提出了这个错误:

java.lang.IllegalStateException: Could not resolve Object Id [B] (for [simple
type, class some.package.graph.Node]) -- unresolved forward-reference?

I even changed the Label of the edges because I thought the same property name might confuse Hymanson here, but that didn't help either...

我什至更改了边缘的标签,因为我认为相同的属性名称可能会在这里混淆 Hymanson,但这也无济于事......

My guess here is that Hymanson can't reference the Node B, because it is still being constructed (you could say it is actually some kind of root in this example). The only way to fix this seems to construct all the Nodes without the edges and inject them in a second step.

我的猜测是 Hymanson 不能引用 Node B,因为它仍在构建中(在这个例子中你可以说它实际上是某种根)。解决这个问题的唯一方法似乎是构建所有没有边的节点并在第二步中注入它们。