getById 는 왜 deprecated 되었을까? 라는 동기분의 질문에 대한 노아님의 견해인데, 추가로 답변 하단에 남겨주신 findBy~ 메서드와 getBy~ 메서드의 내부 구현에 차이점이 존재한다는 코멘트를 보고 궁금증이 생겨 찾아보았다.
findById 와 getReferenceById 를 예시로 들어보자.
findById 는 CrudRepository 에 있는 메서드이고, getReferenceById 는 JPARepository 에 있는 메서드이다.
//CrudRepository
public interface CrudRepository<T,ID> {
...
Optional<T> findById(ID id);
Iterable<T> findAll();
...
}
//JpaRepository
public interface JpaRepository<T,ID> {
...
T getOne(ID id);
List<T> findAll();
...
}
두 메서드가 하는 일은 식별자인 id 를 통해 entity 를 알 수 있는 것으로 동일한데, 작지만 중요한 차이점이 하나 있는데 바로 메서드 명명이다. CrudRepository 의 find 는 리턴값이 없을 수 있지만, get 은 리턴값이 무조건 있어야 한다. 만약 getBy~ 를 호출했을 때 리턴값이 없으면 예외를 일으킨다. 이름 자체도 find 는 찾는 것이고, get 은 가져오는 것이다.
메서드 설명란을 보면, findById 는 엔티티가 있을 경우 반환하고, 만약 없을 경우 empty() 를 반환한다. 빈 목록에 대한 예외처리가 따로 없기 때문에 이 메서드를 호출할 때 엔티티가 없는 경우도 생각해서 개발자가 어떠한 처리를 해주어야 한다. (ID 가 null 일 경우는 IllegalArgumentException 예외를 던진다.)
반면 getReferenceById 는 엔티티(에 대한 참조) 를 반환하고, 없는 경우 EntityNotFoundException 예외를 던진다. 이 경우 엔티티가 존재하지 않으면 invalid 상태이다. 하지만 알아서 예외를 던져주기 때문에 이 메서드를 호출할 시 따로 어떤 처리를 해주지 않아도 된다.
간단한 사용 예시를 살펴보자. 예를 들어, 서점을 구현했다고 가정하면, 이 서점에서 사용자는 제목으로 책을 검색하게 된다. 이 경우 결과값은 없을 수도 있다. 사용자가 오타를 내서 검색을 했거나, 실제 해당 책이 이 서점에 존재하지 않을 수 있기 때문이다. 이 때 findById 를 사용한다.
만약 사용자가 원하는 책을 찾아서 주문까지 완료했다고 가정해보자. 서점은 해당 주문에 대한 결제를 처리하기 위해 사용자에게 인보이스를 보내야 한다. 이 경우, 주문을 로드하고 사용자가 구매한 책을 조회하여 해당 책의 가격을 알아야 한다. 책을 주문한 히스토리가 무조건 있어야 하는 것이다. 이 때 getReferenceById 를 사용한다.
추가로 단순히 Optional.empty() 를 반환하는지, 혹은 내부에서 예외를 발생시키는지의 차이 말고도 다른 점이 있다. 바로 lazy loading (지연 로딩) 이다.
getReferenceById 메서드로 반환된 객체는 내부의 정보를 요청하는 시점에 DB 를 조회한다. 조금 더 자세히 말하자면, getReferenceById 는 EntityManager 의 getReference 메서드를 호출하여 참조값만 가져온 후, 조회된 entity 의 내부 값이 필요해지는 시점에 lazy loading 으로 DB 를 조회해 값을 가져온다. 즉, 내부의 값을 필요로 하지 않고, 다른 객체에게 할당하는 목적으로만 조회하는 경우 getReferenceById 가 성능상 이점이 있을 수 있다는 것이다.
이런 의미에서 deprecated 된 getById 보다는 getReferenceById 가 참조값만 가져오는 메서드라는 점에서 훨씬 더 정확한 의미로 전달되는 것 같다.
참고 :
'TIL' 카테고리의 다른 글
JAVA Stream (스트림) (22.10.29 TIL) (0) | 2022.10.29 |
---|---|
미래 그려보기 (22.10.28 TIL) (0) | 2022.10.28 |
Java 제네릭스 (Generics) (22.10.26 TIL) (0) | 2022.10.26 |
Java 다형성, instanceof (22.10.25 TIL) (0) | 2022.10.25 |
Java Arrays 클래스 (22.10.24 TIL) (0) | 2022.10.24 |
댓글