Skip to content

Conversation

@gulddaggi
Copy link

Jackson 순환 참조 문제 이해 및 해결

문제 및 에러 발생 확인

1. 순환 참조 문제

  • 두 Entity Classroom과 Student는 양방향 연관관계로 구성

    • Classroom : @OneToMany를 통해 여러 개의 Student Entity를 포함 -> 일대다 관계 형성
    • Student : @ManyToOne을 통해 하나의 Classroom Entity를 참조 -> 다대일 관계 형성
  • 순환 참조 발생

    • 원인 : JPA에서 양방향 연관관계를 설정한 상태에서, JSON 직렬화 시 객체 간 참조가 계속됨으로써 순환 참조가 발생
// 테스트 코드 실행 결과 생성된 에러 문구
Document nesting depth (1002) exceeds the maximum allowed (1000, from `StreamWriteConstraints.getMaxNestingDepth()`)
(through reference chain: com.example.jpapractice.entity.ClassRoom["students"]
->java.util.ArrayList[0]
->com.example.jpapractice.entity.Student["classRoom"]
->com.example.jpapractice.entity.ClassRoom["students"]
->java.util.ArrayList[0]
->(이하 생략)

2. 프록시 직렬화 에러

  • 프록시 직렬화 에러를 발생시키기 위해 코드 수정을 진행

    • Student : classRoom 변수에 @ManyToOne(fetch = FetchType.LAZY) 설정(fetch의 기본값은 FetchType.EAGER)
    • ClassRoom : students 변수에 @JsonIgnore 설정
  • 프록시 직렬화 에러 발생

    • 원인 : 위와 같은 설정 후 /api/students/{id} 호출 시, Student 엔티티의 classRoom 필드는 @ManyToOne(fetch = LAZY)로 설정되어 있어 프록시 객체(Hibernate의 ByteBuddy 기반 동적 프록시)로 초기화.
      이는 실제 ClassRoom 객체가 아니라, 내부적으로 ByteBuddyInterceptor를 통해 실제 데이터를 지연 로딩할 수 있는 구조로 되어 있음
      -> JSON 직렬화 시점에 프록시 객체는 일반 POJO(Plain Old Java Object)가 아니므로, Jackson은 내부 필드를 직렬화할 수 없어 예외를 던져 에러 발생.
// swagger 에서 /api/students/{id} 호출 결과 생성된 에러 문구
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer
(to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.example.jpapractice.entity.Student["classRoom"]
->com.example.jpapractice.entity.ClassRoom$HibernateProxy["hibernateLazyInitializer"])

  • 추가로 학습 시 순환 참조 발생 여부를 확인할 수 있는 테스트코드도 작성하였습니다.

@gulddaggi gulddaggi self-assigned this May 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants