728x90
Team(팀) 테이블과 Department(부서) 테이블을 양방향 연관관계로 맺고, 이를 조회하거나 디버깅하려고 할 때 다음과 같은 에러가 발생했다.
Method threw 'java.lang.StackOverflowError' exception.
Cannot evaluate com.example.Team.toString()
원인
JPA에서 Team ↔ Department 관계를 @OneToMany
, @ManyToOne
으로 양방향으로 설정하면 다음과 같은 문제가 발생할 수 있다.
- Team → Department : @ManyToOne
- Department → List<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
반응형
'DB > JPA' 카테고리의 다른 글
JPA - DB 테이블 자동 생성과 양방향 연관관계 설정 (0) | 2021.02.17 |
---|---|
질문할 때 DB 테이블 구조를 깔끔하게 올리는 방법과 JPA 관계 매핑 정리 (0) | 2020.10.12 |
JPA 양방향 매핑 시 발생한 무한 순환 참조 에러 (0) | 2020.10.12 |
JPA에서 단일 데이터 조회하기 (0) | 2020.10.07 |
JPA에서 @Transient 사용하기 (0) | 2020.09.26 |