Direct Self-Reference Leading to Cycle Exception

I have a class; something like the following:

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;
  }

}

And a class that extends the class above

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();
  }

}

Now, I have an object of type DailyActivity, and when I try to convert it into a JSON string, I get the following exception:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Direct self-reference leading to cycle (through reference chain: com.pr.analysis.DailyActivity["previous"])

I have looked for solution on google but the solution which I get asks to put jsonIgnore to previous value which is not what I intent to do. Has anyone faced the same issue? Thanks

EDIT I know there is a cycle in the class and I am asking how to deserialize the class which has a self reference?

6 Answers

In this case you need to annotate the relationships with @JsonManagedReference and @JsonBackReference like this:

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

And

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

There is a nice example here

SerializationFeature has a property called FAIL_ON_SELF_REFERENCES default is true but you can set to false to skip this kind of exception.

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

If you are using SpringBoot you can simply add spring.jackson.serialization.fail-on-self-references=false in your application.properties

2

The self-reference is here:

public class DailyActivity extends ElasticSearchValue<DailyActivity> {

You're saying DailyActivity is an ElasticSearchValue<DailyActivity>, which is by itself an ElasticSearchValue<ElasticSearchValue<DailyActivity>>, and this goes on infinitely...

Update: I would break that in two classes. Create DailyActivity without subclassing ElasticSearchValue:

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

then create another class like:

public class ElacticDailyActivity extends ElasticSearchValue<DailyActivity> {
1

Try @JsonIdentityInfo annotation as given in this example. More details here

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

    public Identifiable next;
}
1

Please refer to related question and a sensible way of handling this in my opinion.

In current case it would help to annotate 'previous' like below

@JsonIgnoreProperties({"previous"})//... along with other annotations
private T previous;

I guess somewhere in your code. The previous of some instance of DailyActivity point to itself.

2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Sophia Al-Mansoor

Sophia Al-Mansoor

Global Business & E-Commerce Reporter

Sophia analyzes international trade, startup ecosystems, retail transformation, and supply chain logistics for modern digital publications.

Share this article
Twitter Facebook Pinterest