[英]'Direct self-reference leading to cycle' Jackson and inheritance
我有一堂這樣的課:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Audited
@DiscriminatorColumn(name = "tipo_hito")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = { "idHito" })
@XmlRootElement(name = "Hito")
public abstract class Hito implements Ordenable {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
@Column(name = "idhito", nullable = false)
private Long idHito;
public Long getIdHito() { return idHito; }
public void setIdHito(Long idHito) { this.idHito = idHito; }
}
還有一個擴展了上述類的類
@MappedSuperclass
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {..., "successors", "predecessors", ...})
@XmlRootElement(name = "HitoOrdenable")
public abstract class HitoOrdenable extends Hito {
@XmlElement(name = "predecessors")
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "succession", joinColumns = { @JoinColumn(name = "idpredecessor") }, inverseJoinColumns = { @JoinColumn(name = "idsuccessor") })
private Set<Hito> predecessors;
@XmlElement(name = "successors")
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "succession", joinColumns = { @JoinColumn(name = "idsuccessor") }, inverseJoinColumns = { @JoinColumn(name = "idpredecessor") })
private Set<Hito> successors;
// More code...
}
現在,錯誤是當我嘗試獲取HitoOrdenable
。 因為例如,我可以擁有:
Hito1
Hito2-SuccessorOf1
Hito3-SuccessorOf1
Hito4-SuccessorOf3
Hito5
Hito6-SuccessorOf5
因此,當我獲得Hito1
時, Hito1
具有Hito2
和Hito3
后繼者。 但是當我得到Hito2
它的前身是Hito1
。 因此,開始一個“無限循環”。
確切的錯誤是:
com.fasterxml.jackson.databind.JsonMappingException:直接自引用導致循環(通過參考鏈:ar.gob.buenosaires.esb.domain.message.ProyectoRespMsg [“ proyectos”]-> java.util.ArrayList [5] - > ar.gob.buenosaires.domain.Proyecto [ “奧夫拉斯”] - > org.hibernate.collection.internal.PersistentBag [0] - > ar.gob.buenosaires.domain.Obra [ “hitos”] - >的有機hibernate.collection.internal.PersistentBag [0] - > ar.gob.buenosaires.domain.HitoObra [ “hitoOrdenable”])
我試圖在以前的predecessors
設置@JsonIgnore,但是它不起作用。
經過幾天的嘗試。 我們發現的唯一解決方案是添加@JsonIgnoreProperties({"predecessors"})
和@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="idHitoAux")
HitoOrdenable.java
@MappedSuperclass
@XmlType(propOrder = {..., "successors", "predecessors", ...})
@XmlAccessorType(XmlAccessType.FIELD)
@JsonIgnoreProperties({ "predecessors" })
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="idHitoAux")
Hito.java
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Audited
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = { "idHito", "tipoHito"})
@JsonIgnoreProperties({"idHitoAux", "hibernateLazyInitializer", "handler"})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, visible = true, property = "tipoHito")
@JsonSubTypes({
@JsonSubTypes.Type(name = "hito_obra", value = HitoObra.class),
@JsonSubTypes.Type(name = "hito_proyecto", value = HitoProyecto.class)
})<
使用JsonIgnoreProperties可以防止后繼者和前任者之間的無限循環,而使用@JsonIdentityInfo
則是因為如果使用"idHito"
而不是"idHitoAux"
(其等於idHito),則Hibernate會將idHito轉換為null。 因此,使用"idHitoAux"
Hibernate可以識別列表中的每個對象。
PD:在該解決方案之后,我們遇到了abstract class Hito
反序列化問題,因此我們的解決方案是添加@JsonSubTypes
。
問候!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.