杰克逊 - 通过自我引用序列化实体

时间:2016-05-23 10:30:27

标签: java json serialization jackson

我有以下实体:

@Entity
@Table(name = "registry_entry")
@JsonIgnoreProperties(ignoreUnknown = true)
public class RegistryEntry extends GenericEntity {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(unique = true, nullable = false)
  @JsonProperty("id")
  protected Long id;
  ...
  @ManyToMany(fetch = FetchType.EAGER)
  @JoinTable(name = "srv_registry_entry_related_dependence",
    joinColumns = @JoinColumn(name = "id_reg_entry", referencedColumnName = "id"),
    inverseJoinColumns = @JoinColumn(name = "id_related_reg_entry", referencedColumnName = "id"))
  @JsonProperty
  private List<RegistryEntry> relatedRegistryEntries;
  ...
}

假设我们有实体ABB.relatedRegistryEntries包含AA.relatedRegistryEntries包含B

当我尝试序列化AB时,我得到StackOverflowError。如何在此列表中仅序列化id?

2 个答案:

答案 0 :(得分:3)

杰克逊支持@JsonIdentityInfo。这就是您所描述的内容:将此注释添加到类中将使该类的所有实例都使用其他ID字段进行序列化,并且下次需要序列化同一实例时,将写入该ID字段的值而不是整个对象。

但请注意,这不是标准的JSON。通常,通常使用JSON格式,因为它得到了许多库的广泛支持。使用此功能可能会为您的API客户端带来其他问题。

更普遍兼容的方法是在没有自引用字段的情况下序列化自引用对象:

public class RegistryEntry {
        @JsonIgnoreProperties("relatedRegistryEntries")
        private List<RegistryEntry> relatedRegistryEntries;
}

答案 1 :(得分:1)

将此注释添加到我的课程中解决了我的问题。

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

我有一个自引用实体,Jackson为此陷入了无限循环。 尽管有问题的财产是暂时性的,但Jakson仍在尝试序列化并提供问题。