DB/JPA

JPA 양방향 매핑 시 발생한 무한 순환 참조 에러

user-anonymous 2020. 10. 12. 13:23
728x90

JPA에서 엔티티 간 양방향 연관관계를 설정하던 중, Infinite recursion (StackOverflowError) 에러가 발생했다.


nested exception is com.fasterxml.jackson.databind.JsonMappingException: 
Infinite recursion (StackOverflowError)

문제 상황

TestATestB 클래스가 서로 @OneToOne 관계로 얽혀 있고, 양쪽에서 서로를 참조하게 되어 있었다. 이 구조는 직렬화(Jackson을 통한 JSON 변환) 과정에서 무한 루프를 유발한다.

문제 코드


// TestA.java
@OneToOne(targetEntity = TestB.class)
@JoinColumn(name = "hm_name")
TestB testB;

// TestB.java
@OneToOne(targetEntity = TestA.class)
@JoinColumn(name = "hm_email")
TestA testA;

양쪽에서 서로 toString()이나 JSON 변환을 하게 되면 무한히 순환하면서 StackOverflow 에러를 터뜨린다.


해결

Jackson에서 이런 양방향 관계를 처리하려면 어느 한쪽에서만 직렬화를 수행하도록 지정해줘야 한다. 이를 위해 사용하는 어노테이션이 @JsonManagedReference@JsonBackReference다.

 적용 예시


// TestA.java
@JsonManagedReference
@OneToOne(targetEntity = TestB.class)
@JoinColumn(name = "hm_name")
TestB testB;

// TestB.java
@JsonBackReference
@OneToOne(targetEntity = TestA.class)
@JoinColumn(name = "hm_email")
TestA testA;

이렇게 하면 직렬화 시 testA → testB 방향만 JSON으로 출력되고, 반대 방향은 무시된다. 무한 순환 참조도 발생하지 않는다.


참고 정리

  • @JsonManagedReference → JSON 출력 대상 (보통 부모)
  • @JsonBackReference → 출력 생략 대상 (보통 자식)
  • 대안으로 @JsonIgnore를 통해 직렬화 자체를 막는 것도 가능

 

728x90
반응형