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)
문제 상황
TestA
와 TestB
클래스가 서로 @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
반응형