😰테스트 코드를 만들어 돌리던 중 @OneToMany관계에서 계속 에러가 발생하였다.
@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이 발생하였다.
그래서 아래와 같은 순서로 원인을 찾아보았다.
매핑관계를 확인 해 보았지만 다른 테스트에서는 오류가 안 나왔고 아무리 확인해도 매핑은 제대로 한 것을 확인하였기에 첫 번재는 패스하였다.
두 번째는 객체간의 연결을 제대로 안 해 주었는지를 확인하였다. 실제로 연결을 안 한 부분이 있어 제대로 해주었지만 그래도 null값이 생겼다.
마지막으로 세번째는 혹시 영속성 컨텍스트와 관련이 있을 수도 있다 생각이 들어 확인하였지만 매핑관계도 제대로 설정해주었고 영속성 컨텍스트를 flush, clear도 해보았지만 그래도 null이 발생하였다.
그래서 다시 객체를 살피던 중 @Builder를 쓴 것이 에러가 나옴을 알아냈다.
@Builder를 설정하게 되면 모든 객체에 대하여 Builder패턴을 쓸 수 있는데 문제는 Set의 경우 내가 초기화 해주어도 @Builder로 인해 설정을 안 해주면 null이 들어가게 된다. 그래서 테스트를 돌리면 null값의 list가 들어왔던 것이다.
이를 해결 하기위해 아래와 같이 코드를 설정하고 테스트를 통과시켰다.
...생략
@Builder.Default
@OneToMany(mappedBy = "answer")
private Set<AnswerSiteUser> voter = new HashSet<>();
...생략