web-dev-qa-db-fra.com

Auto-référence directe conduisant à une exception de cycle

J'ai un cours; quelque chose comme ceci:

public abstract class ElasticSearchValue<T> {

  private Long txId;
  private Long currentTxId;
  private T previous;

  public Long getTxId() {
    return txId;
  }

  public void setTxId(Long txId) {
    this.txId = txId;
  }

  public Long getCurrentTxId() {
    return currentTxId;
  }

  public void setCurrentTxId(Long currentTxId) {
    this.currentTxId = currentTxId;
  }

  public Object getPrevious() {
    return previous;
  }

  public void setPrevious(T previous) {
    this.previous = previous;
  }

}

Et une classe qui étend la classe ci-dessus

public class DailyActivity extends ElasticSearchValue<DailyActivity> {

  Long agentId;
  Date date;
  Long success;

  public Long getAgentId() {
    return agentId;
  }

  public void setAgentId(Long agentId) {
    this.agentId = agentId;
  }

  public Date getDate() {
    return date;
  }

  public void setDate(Date date) {
    this.date = date;
  }

  public Long getSuccess() {
    return success;
  }

  public void setSuccess(Long success) {
    this.success = success;
  }

  @Override
  public String toString() {
    return agentId + "_" + date.toString();
  }

}

Maintenant, j'ai un objet de type DailyActivity, et lorsque j'essaie de le convertir en chaîne JSON, j'obtiens l'exception suivante:

Provoqué par: com.fasterxml.jackson.databind.JsonMappingException: auto-référence directe menant au cycle (via la chaîne de référence: com.pr.analysis.DailyActivity ["précédente"])

J'ai cherché une solution sur google mais la solution que j'obtiens demande de mettre jsonIgnore à la valeur précédente qui n'est pas ce que j'ai l'intention de faire. Quelqu'un at-il fait face au même problème? Merci

EDIT Je sais qu'il y a un cycle dans la classe et je demande comment désérialiser la classe qui a une auto référence?

16
Global Warrior

Dans ce cas, vous devez annoter les relations avec @ JsonManagedReference et @ JsonBackReference comme ceci:

 @ManyToOne
 @JoinColumn(name = "company_id", referencedColumnName = "id")
 @JsonBackReference
 private Company company 

Et

 @OneToMany(mappedBy="company")
 @JsonManagedReference
 private Set<Employee> employee = new HashSet<Employee>();

Il y a un bel exemple ici

14
borjab

L'auto-référence est ici:

public class DailyActivity extends ElasticSearchValue<DailyActivity> {

Vous dites que DailyActivity est un ElasticSearchValue<DailyActivity>, qui est en soi un ElasticSearchValue<ElasticSearchValue<DailyActivity>>, et cela continue indéfiniment ...

pdate: Je diviserais cela en deux classes. Créez DailyActivity sans sous-classement ElasticSearchValue:

public class DailyActivity {
  // the same content as your class above

puis créez une autre classe comme:

public class ElacticDailyActivity extends ElasticSearchValue<DailyActivity> {
5
ericbn

SerializationFeature possède une propriété appelée FAIL_ON_SELF_REFERENCES la valeur par défaut est true mais vous pouvez définir false pour ignorer ce type d'exception.

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(SerializationFeature.FAIL_ON_SELF_REFERENCES, false);

Si vous utilisez SpringBoot, vous pouvez simplement ajouter spring.jackson.serialization.fail-on-self-references=false dans votre application.properties

4
ValerioMC

Essayez @JsonIdentityInfo annotation comme indiqué dans cet exemple. Plus de détails ici http://wiki.fasterxml.com/JacksonFeatureObjectIdentity

@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class Identifiable
{
    public int value;

    public Identifiable next;
}
2
MFIhsan

Je suppose quelque part dans votre code. Le précédent d'une instance de DailyActivity pointe vers lui-même.

0
Yiheng Wang