부트캠프/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해주었더니 해결되었다.  

comment, schedule 모두 ToString이 정상동작

 

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