Direct self-reference leading to cycle exception

63,386

Solution 1

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

Solution 2

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

Solution 3

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> {

Solution 4

Try @JsonIdentityInfo annotation as given in this example. More details here http://wiki.fasterxml.com/JacksonFeatureObjectIdentity

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

    public Identifiable next;
}

Solution 5

Please refer to related question and a sensible way of handling this in my opinion. https://stackoverflow.com/a/65920426/12594701

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

@JsonIgnoreProperties({"previous"})//... along with other annotations
private T previous;
Share:
63,386

Related videos on Youtube

Global Warrior
Author by

Global Warrior

Developer, into the wild

Updated on August 04, 2022

Comments

  • Global Warrior
    Global Warrior almost 2 years

    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?

  • Global Warrior
    Global Warrior over 10 years
    Ya, it obviously does. Let me re-frame the question how can you deserialize an object which has a self reference?
  • Global Warrior
    Global Warrior over 10 years
    Ya, I know that and am asking how to deserialize such a class?
  • Yiheng Wang
    Yiheng Wang over 10 years
    I don't think you can. I will set the previous to null when it points to itself before send the object. In other end, after recevied the object, change the previous to itself if it's null. Maybe someone else have better idea.
  • Naghaveer R
    Naghaveer R over 7 years
    I'm facing the same issue. I have configured my project as mentioned in above link, but it is not working.
  • Kiran Bhagwat
    Kiran Bhagwat almost 5 years
    Warning: Using this solution code might go into Infinite recursion. e.g.Could not write JSON: Infinite recursion(StackOverflowError)
  • Hammad Dar
    Hammad Dar about 3 years
    This most probably would cause as stated by @KiranBhagwat