목표

: JpaRepository를 상속받은 인터페이스를 이용해 데이터를 조회하는 방법에는 여러가지가 있는데 그 중에 findById()와 getReferenceById()를 이용해 원하는 데이터를 조회할 수 있다. 그렇다면 다른 함수로 존재하는 만큼 둘의 용도에 차이가 있을 것이라고 생각한다. 따라서 둘을 비교해보고 차이를 파악하여 적절한 메서드를 사용하고자 한다. 

 

1. findById()

: 조회할 엔티티의 식별자 id를 통해서 값을 반환하는 메서드이다.

- 리턴 타입: Optional<T>

     - 조회된 엔티티를 Optional로 감싸서 반환한다.

     - 영속성 컨텍스트에 없어도 예외를 던지는 것을 방지할 수 있다.

- 코드를 읽으면 바로 findById()가 실행된다

<코드>

Optional<Author> optionalAuthor = authorRepository.findById(authorId);
        System.out.println("=====================");
        System.out.println(optionalAuthor);

 

<결과>

Hibernate: 
    select
        a1_0.id,
        a1_0.authorName,
        a1_0.email,
        a1_0.password,
        a1_0.postDate,
        a1_0.updateDate 
    from
        author a1_0 
    where
        a1_0.id=?
=====================
Optional[com.example.taskmanagerapp.entity.Author@515b1401]

 

 

2. getReferenceById()

: 조회할 엔티티를 식별자 id를 통해서 값을 반환하는 메서드이다.

- 리턴 타입: T

     - 엔티티의 클래스 타입이다.

     - 영속성 컨텍스트에 없으면 EntityNotFoundException이 발생한다.

- 지연로딩 방식으로 엔티티 사용 전까지 조회를 지연해 프록시 객체로 갖고 있다가 해당 엔티티 객체가 필요한 시점에(출력, 사) 실제 엔티티를 반환한다. 

<코드>

        Author author = authorRepository.getReferenceById(authorId);
        System.out.println("=====================");
        System.out.println(author);

 

<결과>

=====================
Hibernate: 
    select
        a1_0.id,
        a1_0.authorName,
        a1_0.email,
        a1_0.password,
        a1_0.postDate,
        a1_0.updateDate 
    from
        author a1_0 
    where
        a1_0.id=?
com.example.taskmanagerapp.entity.Author@2f1be231

 

- 해당 객체의 id값을 호출할 때는 SQL이 실행되지 않는다.

     - getReferenceById()는 프록시 객체를 반환하는데 이는 내부적으로 id값만 세팅되어 있고 나머지는 초기화되어 있지 않다.

          - 실제 필드 접근 할 때에 프록시 객체가 실체화된다.

          - 프록시: id만 세팅되어 있는 껍데기 객체

 

 

정리

  findById() getReferenceById()
반환 타입 Optional<T> T
동작 방식 Eager Load(즉시 조회) Lazy Load(지연 조회)
쿼리 실행 시점 메서드 호출 시 실제 필드 접근 시점
프록시 사용 X O
예외 발생 여부 X EntityNotFoundException 발생(Entity 없을 시)
용도 데이터 즉시 사용 필요한 경우 엔티티 참조만 필요한 경우

 

+ Recent posts