복붙노트

[SPRING] JSON을 작성할 수 없습니다 : 무한 재귀 (StackOverflowError); 중첩 예외 봄 부팅

SPRING

JSON을 작성할 수 없습니다 : 무한 재귀 (StackOverflowError); 중첩 예외 봄 부팅

이것은 지구 관리자입니다. 저장 후 데이터를 가져 오려고 할 때 오류가 발생합니다. 객체 양식 getDistrict (긴 ID)를 가져 오더라도 같은 방식으로 제안하는 것이 좋습니다. 아주 새로운 봄 환경입니다.

    package com.gad.services;

    import java.util.List;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    import com.gad.repositories.DistrictMasterRepositories;
    import com.gad.rmodels.Districtmaster;
    import com.gad.rmodels.Statemaster;

    @Service
    public class DistricMasterServices {

        @Autowired
        DistrictMasterRepositories districtMasterRepositories;
        @Autowired
        StateMasterServices stateMasterServices;
        List<Districtmaster> districtmaster;

        public Iterable<Districtmaster> savenewdistrict(Long id,Districtmaster districtmaster_rec){
             System.out.println(id);
             Statemaster statemaster=null;
             statemaster = stateMasterServices.getStateById(id);
             System.out.println("savenewdistrict");



                districtmaster_rec.setStatemaster(statemaster);
                districtMasterRepositories.save(districtmaster_rec);
                    Iterable<Districtmaster>districtmaster2 = districtMasterRepositories.findAll();
                    return  districtmaster2;


        }


        public Districtmaster  getDistrict(Long id){
            Districtmaster districtmaster =  districtMasterRepositories.findOne(id);
            return districtmaster;

        }
    }

상태 모델 클래스

 package com.gad.rmodels;
    import static javax.persistence.GenerationType.SEQUENCE;
    import java.util.HashSet;
    import java.util.Set;
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.SequenceGenerator;
    import javax.persistence.Table;

    /**
     * Statemaster generated by hbm2java
     */
    @Entity
    @Table(name="statemaster"
        ,schema="aop_gad_v1"
    )
    public class Statemaster  implements java.io.Serializable {


         private long id;
         private String stateName;
         private Set<Districtmaster> districtmasters = new HashSet<Districtmaster>(0);

        public Statemaster() {
        }


        public Statemaster(long id) {
            this.id = id;
        }
        public Statemaster(long id, String stateName, Set<Districtmaster> districtmasters) {
           this.id = id;
           this.stateName = stateName;
           this.districtmasters = districtmasters;
        }



        @SequenceGenerator(name="generator_statemasterid", sequenceName="aop_gad_v1.gad_statemaster_seq")
        @Id 
        @GeneratedValue(strategy=SEQUENCE, generator="generator_statemasterid")
        @Column(name="id", unique=true, nullable=false)
        public long getId() {
            return this.id;
        }

        public void setId(long id) {
            this.id = id;
        }

        @Column(name="state_name", length=20)
        public String getStateName() {
            return this.stateName;
        }

        public void setStateName(String stateName) {
            this.stateName = stateName;
        }

    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="statemaster")
        public Set<Districtmaster> getDistrictmasters() {
            return this.districtmasters;
        }

        public void setDistrictmasters(Set<Districtmaster> districtmasters) {
            this.districtmasters = districtmasters;
        }




    }

지구 모델

package com.gad.rmodels;


import static javax.persistence.GenerationType.SEQUENCE;

import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

/**
 * Districtmaster generated by hbm2java
 */
@SuppressWarnings("serial")
@Entity
@Table(name="districtmaster",schema="aop_gad_v1")
public class Districtmaster  implements java.io.Serializable {


     private long id;
     private Statemaster statemaster;
     private String districtName;
     private Set<GadGuestHouseMaster> gadGuestHouseMasters = new HashSet<GadGuestHouseMaster>(0);

    public Districtmaster() {
    }


    public Districtmaster(long id) {
        this.id = id;
    }
    public Districtmaster(long id, Statemaster statemaster, String districtName, Set<GadGuestHouseMaster> gadGuestHouseMasters) {
       this.id = id;
       this.statemaster = statemaster;
       this.districtName = districtName;
       this.gadGuestHouseMasters = gadGuestHouseMasters;
    }


     @SequenceGenerator(name="generator_districtmasterid", sequenceName="aop_gad_v1.gad_districtmasterid_seq")
     @Id 
     @GeneratedValue(strategy=SEQUENCE, generator="generator_districtmasterid")
     @Column(name="id", unique=true, nullable=false)
    public long getId() {
        return this.id;
    }

    public void setId(long id) {
        this.id = id;
    }
@ManyToOne(fetch=FetchType.LAZY)

    @JoinColumn(name="district_of_state")
    public Statemaster getStatemaster() {
        return this.statemaster;
    }

    public void setStatemaster(Statemaster statemaster) {
        this.statemaster = statemaster;
    }

    @Column(name="district_name", length=20)
    public String getDistrictName() {
        return this.districtName;
    }

    public void setDistrictName(String districtName) {
        this.districtName = districtName;
    }
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="districtmaster")
    public Set<GadGuestHouseMaster> getGadGuestHouseMasters() {
        return this.gadGuestHouseMasters;
    }

    public void setGadGuestHouseMasters(Set<GadGuestHouseMaster> gadGuestHouseMasters) {
        this.gadGuestHouseMasters = gadGuestHouseMasters;
    }




}

내가 얻은 오류

해결법

  1. ==============================

    1.Statemaster 모델에는 Statemaster 모델의 개체가 포함 된 Districtmaster 모델의 개체가 포함되어 있기 때문에이 문제에 직면 해 있습니다. 이로 인해 무한한 json 재귀가 발생합니다.

    Statemaster 모델에는 Statemaster 모델의 개체가 포함 된 Districtmaster 모델의 개체가 포함되어 있기 때문에이 문제에 직면 해 있습니다. 이로 인해 무한한 json 재귀가 발생합니다.

    이 문제는 3 가지 방법으로 해결할 수 있습니다.

    1 - DTO를 만들고 응답에 표시하려는 필드 만 포함하십시오.

    2 - @JsonManagedReference 및 @JsonBackReference 주석을 사용할 수 있습니다.

    예 : @JsonManagedReference 주석을 Statemaster 모델에 추가하십시오.

    @JsonManagedReference
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="statemaster")
    public Set<Districtmaster> getDistrictmasters() {
        return this.districtmasters;
    }
    

    @JsonBackReference 주석을 Districtmaster 모델에 추가하십시오.

    @JsonBackReference
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="district_of_state")
    public Statemaster getStatemaster() {
        return this.statemaster;
    }
    

    3 - getter 또는 setter 메서드에서 @JsonIgnore 주석을 사용할 수 있습니다.

    @JsonIgnore
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="statemaster")
    public Set<Districtmaster> getDistrictmasters() {
        return this.districtmasters;
    }
    

    그러나이 접근법은 Districtmaster를 응답에서 제외합니다.

  2. ==============================

    2.그것은 json의 Statemaster에게 Districtmaster 세트가 있기 때문입니다. 그리고 각 각의 Districtmaster는 Statemaster를 자체적으로 가지고 있으므로 json에도 넣습니다. 그래서 당신은 무한 재귀를 얻습니다.

    그것은 json의 Statemaster에게 Districtmaster 세트가 있기 때문입니다. 그리고 각 각의 Districtmaster는 Statemaster를 자체적으로 가지고 있으므로 json에도 넣습니다. 그래서 당신은 무한 재귀를 얻습니다.

        @JsonIgnore
        @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, 
        mappedBy="statemaster")
        public Set<Districtmaster> getDistrictmasters() {
            return this.districtmasters;
        }
    

    Set 에 @JsonIgnore 주석을 추가하면 해당 재귀가 방지됩니다. 공용 Statemaster getStatemaster ()에 @JsonIgnore를 둘 수 있습니다.

  3. ==============================

    3.나는 며칠 동안 같은 문제를 겪어 왔지만, @JsonIgnore, @JsonManagedReference 및 @JsonBackReference 주석을 시도하고 심지어 @JsonIdentityInfo 주석을 사용했으며 그 중 아무 것도 작동하지 않았습니다.

    나는 며칠 동안 같은 문제를 겪어 왔지만, @JsonIgnore, @JsonManagedReference 및 @JsonBackReference 주석을 시도하고 심지어 @JsonIdentityInfo 주석을 사용했으며 그 중 아무 것도 작동하지 않았습니다.

    독자 (미래의 독자)가 같은 상황에 있다면 솔루션은 예상보다 쉽습니다. @JsonIgnore 또는 @JsonManagedReference / @JsonBackReference를 속성의 getter에 넣고 속성 자체에는 넣지 마십시오. 그리고 그렇게 될 것입니다.

    다음은이를 수행하는 간단한 예입니다.

    Order와 Product, 그리고 OneToMany 관계라는 두 개의 클래스가 있다고 가정 해보십시오.

    주문 클래스

    public class Order{
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private String id_order;
      private double price;
      @OneToMany(mappedBy = "order")
      @LazyCollection(LazyCollectionOption.FALSE)
      private List<Product> products
      //constructor, getters & setter 
    }
    

    제품 클래스 :

    public class Product{
       @Id
       @GeneratedValue(strategy = GenerationType.AUTO)
       private String id_product;
       private String name;
       @ManyToOne
       @JoinColumn(name = "id_order")
       private Order order;
       //consturctor, getters & setters
     }
    

    따라서 @JsonManagedReference와 @JsonBackReference를 사용하려면 getters에 다음과 같이 추가하십시오.

    public class Order{
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private String id_order;
      private double price;
      @OneToMany(mappedBy = "order")
      @LazyCollection(LazyCollectionOption.FALSE)
      private List<Product> products
      //constructor, getters & setter 
      @JsonManagedReference
      public List<Product> getProducts(){
        return products;
    }
    

    제품 클래스 :

    public class Product{
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      private String id_product;
      private String name;
      @ManyToOne
      @JoinColumn(name = "id_order")
      private Order order;
      //consturctor, getters & setters
      @JsonBackReference
      public Order getOrder(){
        return order;
      }
     }
    
  4. ==============================

    4.문제가 최대 절전 모드 인 것 같습니다. 엔티티 Statemaster를 serialize하려고하면 serializer가 Districtmaster 세트의 serialization을 호출합니다. 차례 차례로 Statemaster를 다시 참조하십시오.

    문제가 최대 절전 모드 인 것 같습니다. 엔티티 Statemaster를 serialize하려고하면 serializer가 Districtmaster 세트의 serialization을 호출합니다. 차례 차례로 Statemaster를 다시 참조하십시오.

    해결할 수있는 두 가지 방법이 있습니다. 1. unproxy 객체

  5. ==============================

    5.이 문제는 양방향 매핑을 처리 할 때 발생합니다. DAO / Entity 클래스에서 @JsonManagedReferenc 및 @JsonBackReference 사용

    이 문제는 양방향 매핑을 처리 할 때 발생합니다. DAO / Entity 클래스에서 @JsonManagedReferenc 및 @JsonBackReference 사용

    @JsonManagedReference는 참조의 앞으로의 부분입니다 - 정상적으로 직렬화됩니다. @JsonBackReference는 참조의 뒷부분입니다. 직렬화에서 생략됩니다.

    (자세히보기)

  6. from https://stackoverflow.com/questions/47693110/could-not-write-json-infinite-recursion-stackoverflowerror-nested-exception by cc-by-sa and MIT license