본문 바로가기

DB/JPA

JPA 양방향 연관관계에서 StackOverflowError 발생한 이유와 해결

728x90

Team(팀) 테이블과 Department(부서) 테이블을 양방향 연관관계로 맺고, 이를 조회하거나 디버깅하려고 할 때 다음과 같은 에러가 발생했다.


Method threw 'java.lang.StackOverflowError' exception. 
Cannot evaluate com.example.Team.toString()

원인

JPA에서 Team ↔ Department 관계를 @OneToMany, @ManyToOne으로 양방향으로 설정하면 다음과 같은 문제가 발생할 수 있다.

  • TeamDepartment : @ManyToOne
  • DepartmentList<Team> : @OneToMany

이때 toString()을 호출하면 Team 안의 Department를 출력하고,
Department는 다시 Team 리스트를 출력하려고 하면서 무한 루프가 발생하여 StackOverflow 에러가 발생하게 된다.

해결 방법

org.apache.commons.lang3.builder.ToStringBuilder를 사용하여 순환 참조를 방지하는 방식으로 해결하였다.


@Override
public String toString() {
    return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
            .append("id", id)
            .append("name", name)
            .toString(); // 연관관계 필드 제외
}

또는 Lombok을 사용하고 있다면 아래와 같이 @ToString(exclude = {"department"}) 등의 옵션도 가능하다.


@ToString(exclude = {"teams"}) // 또는 @ToString(callSuper = true, exclude = {...})
@Entity
public class Department {
    ...
}

💡 추가 팁

  • 연관관계 필드는 toString()에서 제외하자.
  • 디버깅 시 toString() 사용을 조심하자. 로그에 연관관계가 깊은 엔티티를 직접 찍지 말 것.
  • Lombok의 @ToString, 또는 ToStringBuilder로 필요한 필드만 출력하도록 명시하자. 
728x90
반응형