Infinite Recursion with Jackson JSON and Hibernate JPA issue

前端 未结 25 3174
你的背包
你的背包 2020-11-21 07:31

When trying to convert a JPA object that has a bi-directional association into JSON, I keep getting

org.codehaus.jackson.map.JsonMappingException: Infinite          


        
相关标签:
25条回答
  • 2020-11-21 07:50

    I also met the same problem. I used @JsonIdentityInfo's ObjectIdGenerators.PropertyGenerator.class generator type.

    That's my solution:

    @Entity
    @Table(name = "ta_trainee", uniqueConstraints = {@UniqueConstraint(columnNames = {"id"})})
    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
    public class Trainee extends BusinessObject {
    ...
    
    0 讨论(0)
  • 2020-11-21 07:53

    I had this problem, but I didn't want to use annotation in my entities, so I solved by creating a constructor for my class, this constructor must not have a reference back to the entities who references this entity. Let's say this scenario.

    public class A{
       private int id;
       private String code;
       private String name;
       private List<B> bs;
    }
    
    public class B{
       private int id;
       private String code;
       private String name;
       private A a;
    }
    

    If you try to send to the view the class B or A with @ResponseBody it may cause an infinite loop. You can write a constructor in your class and create a query with your entityManager like this.

    "select new A(id, code, name) from A"
    

    This is the class with the constructor.

    public class A{
       private int id;
       private String code;
       private String name;
       private List<B> bs;
    
       public A(){
       }
    
       public A(int id, String code, String name){
          this.id = id;
          this.code = code;
          this.name = name;
       }
    
    }
    

    However, there are some constrictions about this solution, as you can see, in the constructor I did not make a reference to List bs this is because Hibernate does not allow it, at least in version 3.6.10.Final, so when I need to show both entities in a view I do the following.

    public A getAById(int id); //THE A id
    
    public List<B> getBsByAId(int idA); //the A id.
    

    The other problem with this solution, is that if you add or remove a property you must update your constructor and all your queries.

    0 讨论(0)
  • 2020-11-21 07:54

    The new annotation @JsonIgnoreProperties resolves many of the issues with the other options.

    @Entity
    
    public class Material{
       ...    
       @JsonIgnoreProperties("costMaterials")
       private List<Supplier> costSuppliers = new ArrayList<>();
       ...
    }
    
    @Entity
    public class Supplier{
       ...
       @JsonIgnoreProperties("costSuppliers")
       private List<Material> costMaterials = new ArrayList<>();
       ....
    }
    

    Check it out here. It works just like in the documentation:
    http://springquay.blogspot.com/2016/01/new-approach-to-solve-json-recursive.html

    0 讨论(0)
  • 2020-11-21 07:55

    You may use @JsonIgnore to break the cycle (reference).

    You need to import org.codehaus.jackson.annotate.JsonIgnore (legacy versions) or com.fasterxml.jackson.annotation.JsonIgnore (current versions).

    0 讨论(0)
  • 2020-11-21 07:55

    @JsonIgnoreProperties is the answer.

    Use something like this ::

    @OneToMany(mappedBy = "course",fetch=FetchType.EAGER)
    @JsonIgnoreProperties("course")
    private Set<Student> students;
    
    0 讨论(0)
  • 2020-11-21 07:56

    In my case it was enough to change relation from:

    @OneToMany(mappedBy = "county")
    private List<Town> towns;
    

    to:

    @OneToMany
    private List<Town> towns;
    

    another relation stayed as it was:

    @ManyToOne
    @JoinColumn(name = "county_id")
    private County county;
    
    0 讨论(0)
提交回复
热议问题