Spring Data JPA 사용 시 Repository에서 리턴 타입을 Optional로 바로 받을 수 있도록 지원하고 있습니다.
Optional을 사용하면 반복적인 null 체크
를 줄일 수 있기 때문에 잘 사용하면 매우 편리한 것 같습니다.
Optional 관련하여 사용법을 간략하게 정리해봤습니다.
// AS-IS
@Override
public Sample getSample(final Long id) {
// 값이 없으면 NoSuchElementException
return sampleRepository.findById(id).get();
}
.get()
의 경우 결과값이 null일 경우 NoSuchElementException
발생
orElseThrow()
를 통해 값이 없을 경우 예외를 던져주거나
orElse
, orElseGet
를 통해 값이 없을 경우 값을 지정
//Optional 결과 값이 없을 때 처리
// throw Exception
return sampleRepository.findById(id)
.orElseThrow(IllegalArgumentException::new);
return sampleRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("no such data");
// null Return
return sampleRepository.findById(id)
.orElse(null);
// 비어있는 객체로 Return
return sampleRepository.findById(id)
.orElseGet(Sample::new);
Repository
에서 Optional을 반환하는 경우
원하는 값이 있으면 원하는 객체로 받고 없으면 Exception처리
를 하는 패턴을 사용
Optional은 NPE 방어를 위한 코드를 쉽게 사용하기 위해 사용
// AS-IS
@Override
@Transactional
public Sample updateSample(Long sampleId) {
Optional<Sample> sample = sampleRepository.findById(sampleId);
if(!sample.isPresent()) {
throw new IllegalArgumentException();
}
// 위의 코드를 orElseThrow 사용을 통해 한줄로 줄일 수 있음
...
return sample.get();
}
// TO-BE
@Override
@Transactional
public Sample updateSample(Long sampleId) {
Sample sample = sampleRepository.findById(sampleId)
.orElseThrow(IllegalArgumentException::new); .
...
return sample;
}
// AS-IS
Optional<User> user = userRepository.findById(userId);
if(user.isPresent()) {
vo.setUsername(user.get().getUsername());
vo.setUserNm(user.get().getName());
}
// TO-BE
Optional<UserVO> user = userRepository.findById(userId);
user.ifPresent(u -> {
vo.setUsername(u.getUsername());
vo.setUserNm(u.getName());
});