Spring Boot + JPA 환경에서 Entity 호출 시 JSON Infinite recursion (StackOverflowError)

준커·2023년 4월 11일
1

Spring

목록 보기
2/3
post-thumbnail
post-custom-banner

1. 상황

  • Celeb Entity는 Celeb 타입의 parent와 List 타입의 subCelebList를 갖는다.
    ex) 방탄소년단이라는 Celeb과 진이라는 Celeb이 있다고 가정.
    1. 방탄소년단 Celeb은 parent는 null이고, subCelebList에 진이라는 Celeb이 담겨있다.
    2. 진 Celeb은 parent에 방탄소년단 Celeb이 있고, subCelebList은 null이다.
  • 이때 진 Celeb을 호출 시 [진 -parent-> 방탄소년단 -subCelebList-> 진 -parent-> 방탄소년단...]이라는 구조가 생겨 JSON Infinite recursion (StackOverflowError)가 발생한다.

2. 수정 전

2-1. Celeb Entity

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonPropertyOrder({"id", "parent", "celebCategory", "celebNameKr", "celebNameEn", "celebStatus", "created_at", "updated_at"})
@Table(name = "celeb")
public class Celeb extends BaseEntity {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "celeb_id")
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id")
    private Celeb parent;

    @ManyToOne
    @JoinColumn(name = "celeb_category_id")
    private CelebCategory celebCategory;

    private String celebNameKr;

	private String celebNameEn;

    @Enumerated(EnumType.STRING)
    private CelebStatus celebStatus;

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
    private List<Celeb> subCelebList = new ArrayList<>();

  
}

2-2. 발생하는 Error log

 ERROR 8736 --- [nio-8080-exec-2] c.s.s.g.c.e.GlobalExceptionHandler       : Error: RuntimeException, Class : HttpMessageNotWritableException, Message : Could not write JSON: Infinite recursion (StackOverflowError)

3. 첫 번째 수정

다음 어노테이션 추가

@JsonIgnoreProperties({"subCelebList"})
  • subCelebList를 Json이 무시하게 설정하여 Infinite recursion을 끊어준다.

3-1. Celeb Entity

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonPropertyOrder({"id", "parent", "celebCategory", "celebNameKr", "celebNameEn", "celebStatus", "created_at", "updated_at"})
@JsonIgnoreProperties({"subCelebList"}) // <- 추가
@Table(name = "celeb")
public class Celeb extends BaseEntity {
 	...
 }

3-2. 발생하는 Error log

ERROR 17692 --- [nio-8080-exec-1] c.s.s.g.c.e.GlobalExceptionHandler       : Error: RuntimeException, Class : HttpMessageConversionException, Message : Type definition error: [simple type, class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor]

4. 두 번째 수정

프로퍼티 추가

@JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "subCelebList"})

4-1. Celeb Entity

@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonPropertyOrder({"id", "parent", "celebCategory", "celebNameKr", "celebNameEn", "celebStatus", "created_at", "updated_at"})
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "subCelebList"}) // <- 수정
@Table(name = "celeb")
public class Celeb extends BaseEntity {
 	...
 }

참고

https://blog.naver.com/adamdoha/222214494979

post-custom-banner

0개의 댓글