목표
: 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 없을 시) |
용도 | 데이터 즉시 사용 필요한 경우 | 엔티티 참조만 필요한 경우 |
'Spring' 카테고리의 다른 글
Dispatcher Servlet이란? (0) | 2025.05.23 |
---|---|
JPA 데이터베이스 컬럼명을 카멜케이스로 작성하니까 에러가 발생한다? (2) | 2025.05.15 |
JPA 데이터베이스의 데이터가 계속 사라진다면? (0) | 2025.05.15 |