@Builder시 @OneToMany테스트 에

greenTea·2023년 4월 19일
0

😰테스트 코드를 만들어 돌리던 중 @OneToMany관계에서 계속 에러가 발생하였다.

Answer 객체

@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Setter
@Getter
@Entity
public class Answer extends BaseTime {

    @Id
    @GeneratedValue
    private Long id;

    @Column(columnDefinition = "TEXT")
    private String content;

    @ManyToOne
    private SiteUser author;

    @OneToMany(mappedBy = "answer")
    private Set<AnswerSiteUser> voter = new HashSet<>();

    @ManyToOne(fetch = FetchType.LAZY)
    private Question question;
}

테스트 코드중 일부

...생략
 Answer answer1 = Answer.builder()
                .content(content)
                .question(question)
                .build();
        answerRepository.save(answer1);
        
...생략
        
AnswerSiteUser answerSiteUser = AnswerSiteUser.builder()
                    .answer(answer1)
                    .siteUser(siteUser)
                    .build();
            answerSiteUserRepository.save(answerSiteUser);
            answer1.getVoter().add(answerSiteUser);
...생략

위 코드를 돌리면 계속 voter에서 null이 발생하였다.

그래서 아래와 같은 순서로 원인을 찾아보았다.

  • 매핑관계 설정 확인
  • 객체간의 관계 설정 확인(매핑만 하고 실제 객체를 연결 안해서 발견한 에러인지 확인)
  • 혹시 영속성 컨텍스트와 jpql간의 관계로 인한 에러인지 확인

매핑관계를 확인 해 보았지만 다른 테스트에서는 오류가 안 나왔고 아무리 확인해도 매핑은 제대로 한 것을 확인하였기에 첫 번재는 패스하였다.

두 번째는 객체간의 연결을 제대로 안 해 주었는지를 확인하였다. 실제로 연결을 안 한 부분이 있어 제대로 해주었지만 그래도 null값이 생겼다.

마지막으로 세번째는 혹시 영속성 컨텍스트와 관련이 있을 수도 있다 생각이 들어 확인하였지만 매핑관계도 제대로 설정해주었고 영속성 컨텍스트를 flush, clear도 해보았지만 그래도 null이 발생하였다.

그래서 다시 객체를 살피던 중 @Builder를 쓴 것이 에러가 나옴을 알아냈다.

해결 방법

@Builder를 설정하게 되면 모든 객체에 대하여 Builder패턴을 쓸 수 있는데 문제는 Set의 경우 내가 초기화 해주어도 @Builder로 인해 설정을 안 해주면 null이 들어가게 된다. 그래서 테스트를 돌리면 null값의 list가 들어왔던 것이다.
이를 해결 하기위해 아래와 같이 코드를 설정하고 테스트를 통과시켰다.

...생략

@Builder.Default
@OneToMany(mappedBy = "answer")
private Set<AnswerSiteUser> voter = new HashSet<>();

...생략
profile
greenTea입니다.

0개의 댓글