JpaRepository를 사용할 때 우리는 아래와 같은 형태를 사용합니다.

Item : Entity
public interface ItemRepository extends JpaRepository<Item, Long> {...}

그리고 JpaRepository의 이해를 돕자면 JpaRepository의 상속을 따라가 보면 CrudRepository<T, ID> 형태를 상속받습니다.

 

이곳을 들어가 보면 사용할 메소드를 볼 수 있습니다.

 

사용할 제네릭 타입

  • T : 엔티티
  • ID : 엔티티의 식별자 타입
  • S : 엔티티와 그 자식 타입

주요 메소드

  • C : save
  • R : findById, getById
  • U : EntityManager에서 merge란 기능이 있지만 해당 정보만을 가져와서 save하는 방식을 추천
  • D : delete

 

  • save(S) : 새로운 엔티티는 저장하고 이미 있는 엔티티는 병합한다. 
  • 내부에서 EntityManager.persist(Object Entity)를 호출한다.
  • 파라미터로 엔티티를 받아서 저장하는 메소드이다.

  • Optional<T> findById(ID) : 엔티티를 하나 조회한다.
  • 내부에서 EntityManager.find()를 호출한다.
  • 파라미터로 아이디를 받아서 ID를 가진 엔티티 혹은 Optional.empty()를 출력한다.

  • findAll() : 모든 엔티티를 조회한다.
  • 정렬(sort)나 페이징(Pageable) 조건을 파라미터로 제공할 수 있다.
  • 파라미터로 ID를 받아서 ID를 가진 엔티티 혹은 Optional.empty()를 출력한다.

  • count() : 엔티티의 숫자를 조회한다.
  • 모든 엔티티를 출력한다.

  • delete(T) : 엔티티 하나를 삭제한다.
  • 내부에서 EntityManager.remove() 호출
  • 파라미터로 엔티티를 받아서 해당 엔티티를 삭제한다.

  • getById(ID) : 엔티티를 프록시로 조회한다.
  • 내부에서 EntityManager.getReference() 호출(getOne은 Deprecated)
  • 파라미터로 아이디를 받아서 주어진 식별자를 가진 엔티티에 대한 참조

 

이 중에서 유사한 형태가 getById(ID) 메소드와 findById(ID)를 비교해보겠습니다.

 

가장 간단히 생각해 보면 get VS find의 차이라고 생각합니다.

 

get이라는 영어 단어는 '가져오기' VS find라는 영어 단어는 '찾기'입니다.

 

간단히 말하면 get은 DB에서 정보를 가지지 않고, find는 DB에서 정보를 가지고 옵니다.

 

getById(ID)

  • 주어진 식별자를 가진 엔티티에 대한 참조를 반환합니다.
  • 즉, getById(ID)는 내부적으로 EntityManager.getReference() 메소드를 호출합니다.
  • 그래서 이 메소드는 DB에 충돌하지 않고 항상 프록시를 반환합니다.
  • 상태를 Lazy하게 가져올 수 있는 인스턴스를 가져온다.
  • 요청된 인스턴스가 DB에 없으면 인스턴스 상태에 처음 액세스 할 때 EntityNotFoundException이 발생한다.
  • 애플리케이션은 엔티티 관리자가 열려있는 동안 애플리케이션이 액세스 하지 않는 한 분리 시 인스턴스 상태를 사용할 수 있을 것으로 예상해서는 안된다.
  • 리턴된 프록시 오브젝트의 특성에 실제로 액세스 할 때까지 DB에 도달하지 않으므로 JVM에서 DB 왕복을 피한다.
  • 객체의 속성에 액세스할 필요가 없는 경우에만 유용

 

findById(ID)

  • 실제로 DB에 도달하고 실제 오브젝트 맵핑을 DB의 행에 리턴한다.
  • DB에 레코드가 없는 경우 리턴하는 것은 EAGER을 가져온 것이다.
  • 주어진 ID에 대한 엔티티를 실제로 로드
  • 모든 속성에 액세스 할 수 있도록 객체가 로드됨
  • 주어진 ID에 해당하는 실제 객체가 존재하지 않으면 null을 반환
  • DB에 대한 추가 왕복이 필요

 

마지막으로 get은 DB를 사용할 필요가 없을 때, find는 DB를 사용해야 할 때 사용해야 겠다는 생각이 들었다.

 

추가적으로 이해를 위해서는 EntityManager를 공부해야 하겠다는 생각이 들었다.