【问题标题】:Jackson JSON infinite recursion without omiting anything from the serialization杰克逊 JSON 无限递归,没有从序列化中省略任何内容
【发布时间】:2018-09-15 14:09:36
【问题描述】:

我想序列化并最终反序列化一个对象以执行导出/导入操作。由于提供了扩展注释,我使用 Jackson 库。我确实通过使用最新的标签@JsonManagedReference、@JsonBackReference 来打破无限递归。但是这里的问题@JsonBackReference 确实省略了 json 文件中的注释部分,因此我无法在导入时设置关系。

可以显示实体之间的关系:

public class A{
   @Id
   @Column(name = "ID", unique = true, precision = 20)
   @SequenceGenerator(name = "a_generator", sequenceName = 
         "SEQ_A", initialValue = 1, allocationSize = 1)
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = 
   "a_generator")
   private Long id;

   @OneToMany(cascade = CascadeType.ALL, mappedBy = "metricDefinition", 
         fetch = FetchType.LAZY, orphanRemoval = true)
   @Fetch(FetchMode.SELECT)
   @NotAudited
   @JsonManagedReference
   private Set<B> bSet= new HashSet<B>();

}

public class B{

@Id
@Column(name = "id", unique = true, precision = 20)
@SequenceGenerator(name = "b_generator", sequenceName = "seq_b", initialValue = 1, allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "b_generator")
private Long id;

@ManyToOne(cascade = {CascadeType.REFRESH})
@JoinColumn(name = "a_id")
@Fetch(FetchMode.SELECT)
@JsonBackReference(value = "a-b")
private A a;

@ManyToOne(cascade = {CascadeType.REFRESH})
@JoinColumn(name = "ref_a_id")
@Fetch(FetchMode.SELECT)
@JsonBackReference(value = "a-ref")
private A refA;


@Column(name = "is_optional")
@Fetch(FetchMode.SELECT)
private boolean isOptional;

@Column(name = "name")
@Fetch(FetchMode.SELECT)
private String name;

当我序列化任何 A 对象时,它会序列化包含的 B,但省略了引用的 A 和 refA。因此,当我导入 A 对象时,当然 B 也会被导入,但我确实想要设置对象之间的关系。

有什么想法可以在不省略引用的一侧的情况下打破无限递归吗?

提前致谢

【问题讨论】:

    标签: json hibernate serialization jackson


    【解决方案1】:

    我也尝试根据给出类似问题的答案使用下面的陈述,但它不起作用,所以我问了上面的问题。

    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
            property = "@id")
    

    打破循环是不够的。您还应该在类的 id 属性中添加以下注释。

      @JsonProperty("id")
    

    【讨论】:

      【解决方案2】:

      我们可以尝试通过以下 3 种方式在 Parent 端或 Child 端打破循环

      • 使用@JsonManagedReference 和@JsonBackReference
      • 使用@JsonIdentityInfo
      • 使用@JsonIgnore

      使用@JsonIdentityInfo

      @Entity
      @Table(name = "nodes")
      @JsonIdentityInfo(
                generator = ObjectIdGenerators.PropertyGenerator.class, 
                property = "id")
      public class Node {
          ...
      }
      
      
      
      @Entity
      @Table(name = "relations")
      @JsonIdentityInfo(
                generator = ObjectIdGenerators.PropertyGenerator.class, 
                property = "id")
      public class Relation {
          ...
      }
      

      更多详细信息请参阅here,最后附上工作演示。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-10
        • 2021-03-10
        • 1970-01-01
        • 2011-03-20
        相关资源
        最近更新 更多