«Прямая ссылка на себя, ведущая к циклу» Джексон и наследство - PullRequest
0 голосов
/ 28 июня 2018

У меня есть класс что-то вроде этого:

@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, у него есть наследники Hito2 и Hito3. Но когда я получаю Hito2, у него есть предшественник Hito1. Так что начните «бесконечный цикл».

Точная ошибка:

com.fasterxml.jackson.databind.JsonMappingException: Direct самоссылка, ведущая к циклу (через цепочку ссылок: ar.gob.buenosaires.esb.domain.message.ProyectoRespMsg [ "Proyectos"] -> java.util.ArrayList [5] -> ar.gob.buenosaires.domain.Proyecto [ "Obras"] -> org.hibernate. collection.internal.PersistentBag [0] -> [ar.gob.buenosaires.domain.Obra "Hitos"] -> org.hibernate.collection.internal.PersistentBag [0] -> ar.gob.buenosaires.domain.HitoObra [ "hitoOrdenable"])

Я пытался установить @JsonIgnore в predecessors, но он не работает.

1 Ответ

0 голосов
/ 09 июля 2018

После нескольких дней попыток. Единственное решение, которое мы нашли, это добавить @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 в ноль. Таким образом, с помощью "idHitoAux" Hibernate может идентифицировать каждый объект в списке.

PD: После этого решения у нас была проблема с десериализацией abstract class Hito, поэтому наше решение было добавить @JsonSubTypes.

Привет!

...