부트캠프/TIL
[부트캠프] TIL - 개인과제 Test Code
purple95
2024. 8. 27. 20:19
문제상황

원인
@ToString
@NoArgsConstructor
@Table(name = "schedules")
public class Schedule extends Timestamped {
@ToString
@Table(name = "comments")
public class Comment extends Timestamped {
//연관관계에 있는 두 Entity 모두에게 @ToString을 사용한 경우
연관관계에 있는 두 Entity에게 @ToString을 달고 출력 테스트를 진행했을 때 StackOverFlow 에러가 발생했다.
상황은 이렇습니다.
@Test
@Transactional
@Rollback
public void getComment(){
//createComment() 테스트메소드 @Rollback(value=false)를 설정
//schedule_id = 2L 과 schedule_id = 2L을 외래키로 갖는 Comment 하나(comment_id=5L)가 DB에 들어간 상태
//이 Comment 정보를 Get하는 테스트
// scheduleId 값으로 Schedule 검색
Schedule schedule = scheduleRepository.findById(2L).orElseThrow(() -> new RuntimeException("해당 id값을 가진 스케쥴 데이터가 존재하지 않습니다."));
// 검색한 Schedule의 comments에 commentId값으로 Comment 검색
List<Comment> commentsInSchedule = schedule.getComments();
Comment comment = commentsInSchedule.stream().filter(c -> c.getComment_id().equals(5L))
.findFirst().orElseThrow(() -> new RuntimeException("해당 id값을 가진 댓글 데이터가 존재하지 않습니다."));
// @ToString 어노테이션 작성 필요.
System.out.println("Get한 Comment : "+comment);
}
Get 해온 Comment의 내용을 확인하는 테스트 코드입니다, 한번에 정보를 확인하고자 Comment에 @ToString 어노테이션을 Lombok을 사용하여 달아주었고. 그 결과

예상했던 올바른 값을 가져와 출력하는데 성공했습니다, 하지만 연관관계에 있는 schedule 의 내용이
@ToString이 없었기 때문에 저렇게 출력이되었고, 저부분도 같이 확인하면 좋겠다 라는 생각에 Schedule 엔티티에도
@ToString을 달아준 것이 원인이었습니다.
이에 대한 검색을 진행해 보았고 원인은 다음과 같습니다.
ORM 프레임워크인 JPA를 사용하여 DB설계를 진행하다보면 단방향이 아닌 양방향 연관관계를 맺게된다.
이 때 관계를 맺은 두 엔티티가 서로 toString을 호출하면서 무한 반복되어 StackOverFlow 에러가 발생하는 경우가 있다.
출처: https://skysoo1111.tistory.com/44 [source:티스토리]
해결방법
@ToString(exclude = "comments")
연관관계 참조변수인 comments를 exclude해주었더니 해결되었다.


Lombok이 편리한 기능이지만, 모든상황에 만능이 아닌거같습니다, 때로는 이런 예외상황에 대해 해결이 필요하겠습니다.