当前位置: 首页 > 知识库问答 >
问题:

Jackson:如何通过仅在子集合中添加ID字段来防止递归调用

郎河
2023-03-14

我想简化我的问题。我有一个父母和一个子实体。

public class Parent {
  private String name;
  @OneToMany
  private List<Child> childs;
}

public class Child {
  private String name;
  @ManyToOne
  private Parent parent;
}

我想做的是当我序列化这些实体时,它应该是这样的。

{
  "parentList": [
    {
      "id": "1",
      "name": "parent",
      "childs": [
        {
          "id": "1",
          "name": "chiled",
          "parent" : "1"
        }
      ],
    }
  ]
}

{
  "childList": [
    {
      "id": "1",
      "name": "child",
      "parent": [
        {
          "id": "1",
          "name": "parent",
          "childs": [
            {
              "id": "1",
            }
        }
      ],
    }
  ]
}

像这样:

Parent -> Child -> parentID
Child -> Parent -> childID

如果我像你在下面看到的那样更新我的实体。

public class Parent {
  private String name;
  @JsonIdentityReference(alwaysAsId = true)
  @OneToMany
  private List<Child> childs;
}

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Child {
  private String name;
  @JsonIdentityReference(alwaysAsId = true)
  @ManyToOne
  private Parent parent;
}

通过这种设置,我几乎得到了我想要的东西。

Child -> Parent -> ChildID (good)
Parent -> ChildID (bad)

我需要父母拥有整个儿童实体,而该儿童实体应该只有父母ID。如果我将@JsonIdtyInfo添加到两个实体,则结果如下所示:

Child -> parentID (bad)
Parent -> childID (bad)

如果我从两者中删除@JsonIdtyInfo,那么我又遇到了递归问题。

不知道如何得到我想要的。

共有2个答案

宣冥夜
2023-03-14

这是预期的行为。通常你不会想做你提议的事情,所以杰克逊默认情况下会考虑到这一点。

但是,由于Jackson只不过是一个java库,您可以扩展和修改它以满足您的需求。我的第一个建议是为父对象创建不同的Scopes-

尽管如此,重要的是要理解为什么这不是默认行为:

如果在一个关系中,的关系中,只能有一个s可以有多个s,那么:

  A         B            C
Child -> Parent -> List<ChildID>
  • A和B是不同的。
  • A包含在C中。
  • C还可以包含其他孩子

但是,

  A         B                   C (missing)
Parent -> List<ChildID> ----> Parent
  • B包含多个子
  • 每个缺失的C都等于A

所以,如果你的问题只出现在你接近家长获取列表时

因此,您不需要缺少的C,因为它已经是元素A了。

希望这有帮助!

李胡媚
2023-03-14

尝试添加“JsonIgnore”注释,以防止不需要的数据从parant实体进入子实体。

    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
    public class Child {
      private String name;
      @JsonIdentityReference(alwaysAsId = true)
      @ManyToOne
      @JsonIgnore      <- HERE
      private Parent parent;
    }
 类似资料:
  • 我对spring rest api有点陌生。我有两个具有单向多对一关系的实体。 假设我在城市表中已经有一些城市。当我想使用http post方法添加城市id为2的新用户时,我必须执行以下操作: 如您所见,我必须首先将城市ID分组到城市实体中。没有分组,我怎么做?这样地:

  • 问题内容: 我有点喜欢Spring Rest API。我有两个具有单向多对一关系的实体。 假设我在城市表中已经有一些城市。当我想使用http post方法添加城市ID为2的新用户时,我必须执行以下操作: 正如你所看到的,我不得不集团内实体第一。没有分组怎么办?像这样 : 问题答案: 您可以使用 链接 用于指示属性应“未包装”序列化的注释;也就是说,如果将其序列化为JSON对象,则其属性将作为其包含

  • 映射可能有大量的空值和空键,我不希望空值被序列化。 对于正在序列化的所有foo,我不想序列化foo中引用的null对象。 实现这一点的最佳方法是什么?我正在我的项目中使用Jackson-Core1.9和Jackson-Mapper1.9 JAR。

  • 这是一个关于Jackson2.3的问题,我不可能更改到其他框架。 我想使用Jackson2.3将对象序列化到json。一些对象来自实现特定(外部)接口的第三方库。我想实现的是防止那些对象中的某些字段被序列化。我没有修改这个类的权限,所以@jsonIgnore不会删除它。下面是一个例子 (我不认为有一个叫做Some_Serializer_That_Can_Ignore_Password的东西,我想要

  • 如何使用递归在列表的最后添加一个项目?我想通过递归添加列表的最后一个,但不能这样做,因为我通过指针指向最后一个元素,所以它返回添加的元素和最后一个元素,而不是整个列表。

  • 问题内容: 我想通过杰克逊进行序列化。现在,我要在序列化过程中进行以下两项设置: Map可以具有大量的null值和null键,我不希望将null序列化。 对于所有要序列化的Foos,我不想序列化Foo中引用的空对象。 实现此目标的最佳方法是什么?我在我的项目中使用jackson-core1.9和jackson-mapper1.9 jar。 问题答案: 如果合理地更改要序列化的原始数据结构以更好地表