[JAVA] JPA 1:N(일대다) JSON 직렬화 순환 참조 문제

2022. 6. 15. 15:29Web

1. JPA 1:N 양방향 맵핑 

  - 이런 맵핑은 공식적으로 존재하지는 않는다.

  - @ManyToOne과 @JoinColumn을 사용해서 연간관계를 맵핑하면, 1:N 단방향 맵핑이 되어버린다.

  - 단방향 맵핑은 성능상 좋지않은 문제점이 있다. 

  - 그걸 막기위해 insetable, updatable 설정을 False 설정하고 읽기 전용 필드로 사용해서 양방향 맵핑처럼

    사용하는 것이다.

 

2. Error 

  - 하지만 이렇게 할경우 해당 에러를 마주칠 수있다.

java.lang.IllegalStateException: Cannot call sendError() after the response has been committed

  - 각 테이블이 서로를 참조하여 무한 재귀함수가 실행함으로서 발생되는 에러이다.

 

3. 해결방법

  - 첫번째 해결방법으로 Entity 대신 DTO 로 반환

     - 가장 추천하는 방법이다.

     - Entity 클래스는 데이터베이스와 맞닿는 핵심 클래스이므로 Entity 클래스를 Request/Response 클래스로 사용하는것은

       별로 추천하지 않는다.

     - 컨트롤러에서 Response 값으로 여러 테이블을 조인해야하는 경우가 많으므로, DB Layer와 View Layer 의 역할분리를 

        신경써서 개발하자

     - 객체지향에서는 역할과 책임은 중요한 요소이다.

 

 

   - 두번째 해결방법 @JsonManagedReference / @JsonBackReference 어노테이션 사용

      - @JsonManagedReference

         연관관계 주인 반대 Entity에 선언

         정상적으로 직렬화 수행

    - @JsonBackReference

       연관관계 주인 Entity에 선언

       직렬화가 되지 않도록 수행

   - 세번째 해결방법 @JsonIgnore 어노테이션 사용

   - @JsonIgnore

      양방향 관계를 가지고 있는 두 엔티티 중 하나의 엔티티의 참조필드에 직렬화를 제외시키는 방법

      JSON 직렬화 과정에서 해당 어노테이션이 선언된 필드는 직렬화 대상에서 제외(데이터 전달 불가)