-
JPA의 리턴타입이 Optional인 이유JPA 2023. 1. 19. 23:17
다음과 같이 JPA에서 제공하는 findById 메소드를 이용하여 해당하는 StudyGroup을 가져오려고 하였는데, 컴파일 에러가 나타났다.
아래 처럼 Optional로 리턴타입을 감싸줌으로써 컴파일 에러를 해결할 수 있다.
원인은 CrudRepository 인터페이스에 있다.
Repository 인터페이스를 만들 때 JPA를 사용하기 위해 JpaRepository를 상속받는다.
JpaRepository 인터페이스의 find와 관련된 메서드에는 CrudRepository 를 확인하라고 적혀있다.
CrudRepository 인터페이스의 findById 메서드를 확인해보면 리턴값이 Optional로 고정되어있다.
Optional을 사용하면 좋은 점이 무엇이 있을까?
Optional은 반복적인 null 처리를 도와주는 Wrapper 클래스이다.
Optional 클래스와 해당 클래스가 제공하는 orElse 또는 orElseGet 메서드를 이용하면 쉽게 NPE 처리가 가능하다.
메서드명 특징 orElseThrow(NullPointerException::new) null이라면 함수형 파라미터로 생성한 예외(NullPointerException)를 발생시킨다. orElse(person) null이면 파라미터(person)를 반환한다. 이때 파라미터(person)은 해당 값이 null이든지 말든지 항상 미리 생성된다. orElseGet null이면 파라미터(person)를 반환한다. 이때 파라미터(person)은 해당 값이 null 일때만 생성된다. 즉 미리 생성되지 않는다. 나는 위의 StudyGroup의 title 정보를 얻어오고자 했는데, Optional 객체이다보니 StudyGroup.getTitle()로는 바로 접근할 수가 없었다.
Optional 객체에 접근하기 위한 방법으로는,
- get() : Optional 내부에 담긴 객체를 반환한다. 만약 null인 객체라면 NoSuchElementException이 발생한다. 따라서, isPresent() 로 체크한 후에 이 get 메서드를 사용해야 한다.
- orElseThrow(Supplier<? extends X> exceptionSupplier) : Optional 내부에 담긴 객체가 null이 아니라면 담겨 있는 객체를 반환하고, null이라면 인자로 넘겨준 함수형 인자를 통해 생성된 예외를 발생시킨다.
- orElse(T other) : Optional 내부에 담긴 객체가 null이 아니라면 담겨있는 객체를 반환하고, null이라면 인자로 넘겨준 member1이라는 객체를 반환한다.
- orElseGet(Supplier<? extends T> other) : Optional 내부에 담긴 객체가 null이 아니라면 담겨있는 객체를 반환하고, null이라면 인자로 넘겨준 함수형 인자를 통해 생성된 객체를 반환한다.
위의 코드는 게시물 수정을 테스트하기 위해, 이미 등록되어 있는 게시글을 가져오는 경우이기 때문에, null이 반환되어서는 안된다.
그래서 orElseThrow를 통해 studyGroup 객체의 title을 호출했다.
결과적으로, 수정 전 객체의 title 값과 수정 후 객체의 title 값이 변했는지 확인할 수 있었다.
'JPA' 카테고리의 다른 글
N+1 Select 문제 (0) 2023.02.14 @EntityGraph (0) 2023.02.14 JPA Enum Type (@Enumerated, EnumType) (0) 2023.01.25 @ManyToMany 사용 시 주의할 점 (List, Set) (0) 2023.01.25