Spring 7기 프로젝트/코드 개선 + 테스트 코드 프로젝트
[트러블슈팅] Spring JPA에서 연관관계 null 체크의 중요성
JuNo_12
2025. 6. 5. 15:04
문제 상황
과제 진행 중, 다음과 같은 테스트가 실패했습니다.
@Test
void todo의_user가_null인_경우_예외가_발생한다() {
// given
Todo todo = new Todo();
ReflectionTestUtils.setField(todo, "user", null);
// when & then
assertThrows(InvalidRequestException.class, () ->
managerService.saveManager(authUser, todoId, request)
);
}
원인 분석
기존 서비스 코드에서는 null 체크 없이 바로 연관관계 객체의 메서드를 호출했습니다.
// 문제가 있는 코드
if (!ObjectUtils.nullSafeEquals(user.getId(), todo.getUser().getId())) {
// todo.getUser()가 null이면 NPE 발생!
}
해결 방법
연관관계 객체에 접근하기 전 null 체크를 추가했습니다.
// 개선된 코드
if (todo.getUser() == null) {
throw new InvalidRequestException("유효하지 않은 일정입니다.");
}
if (!ObjectUtils.nullSafeEquals(user.getId(), todo.getUser().getId())) {
throw new InvalidRequestException("권한이 없습니다.");
}
왜 이런 상황이 발생할까?
@JoinColumn(nullable = false)로 설정했어도 다음 상황에서 null이 가능합니다:
- 동시성 문제: 트랜잭션 처리 중 중간 상태
- 데이터 마이그레이션: 불완전한 데이터 임시 저장
- 외부 시스템 연동: 불완전한 데이터 수신
- 개발/테스트 환경: 수동 데이터 입력
느낀점
DB 제약조건만으로는 완벽하지 않다.
애플리케이션 레벨에서의 방어적 프로그래밍이 필요하며, 특히 연관관계 객체에 접근할 때는 항상 null 체크를 하는 것이 안전합니다.
// 좋은 패턴
if (entity.getRelatedEntity() == null) {
throw new BusinessException("적절한 에러 메시지");
}
// 이후 안전하게 사용
entity.getRelatedEntity().someMethod();