[Spring Boot] JPA의 findById vs getReferenceById 의 차이점

nano·2025년 2월 11일

Spring Boot

목록 보기
4/4
post-thumbnail

JPA를 사용하다 보면 특정 엔티티를 조회할 때 findByIdgetReferenceById 두 가지 메서드를 사용할 수 있습니다. 처음 보면 비슷해 보이지만, 동작 방식에서 큰 차이를 보이므로 이를 명확히 이해하고 적절한 상황에서 사용하는 것이 중요합니다.

1. findById(Long id)

findById는 해당 ID에 해당하는 엔티티를 데이터베이스에서 즉시 조회하여 반환하는 메서드이다.

특징

  • 즉시 데이터베이스 조회: 엔티티를 바로 가져와야 하므로 실제로 데이터베이스를 조회함
  • Optional 반환: 조회된 결과를 Optional로 감싸서 반환하므로, 존재 여부를 쉽게 확인 가능
  • 데이터가 없을 경우 Optional.empty() 반환

코드 예시

Optional<User> user = userRepository.findById(1L);
if (user.isPresent()) {
    System.out.println(user.get().getName());
} else {
    System.out.println("User not found");
}

언제 사용해야 할까?

  • 즉시 엔티티의 정보가 필요할 때
  • Null 체크를 Optional을 활용해서 안전하게 처리하고 싶을 때

2. getReferenceById(Long id)

getReferenceById는 프록시 객체를 반환하는 메서드로, 실제 데이터베이스 조회는 필요할 때 수행됩니다. 즉, Lazy Loading(지연 로딩)을 사용합니다.

특징

  • 프록시 객체 반환: 실제 데이터가 아닌 Hibernate가 제공하는 프록시 객체를 반환합니다.
  • 실제 데이터베이스 조회는 사용 시점에 발생
  • 데이터가 존재하지 않으면 EntityNotFoundException 발생

코드 예시

User user = userRepository.getReferenceById(1L);
System.out.println(user.getName()); // 이 시점에서 실제 조회 발생

언제 사용해야 할까?

  • 엔티티가 필요한지 확실하지 않고, 참조만 필요한 경우
  • 즉시 데이터베이스 조회를 피하고 싶을 때 (예: 트랜잭션 내에서 데이터를 사용할 예정일 때)
  • JPA 연관 관계에서 Lazy Loading을 유지하고 싶을 때

3. findById vs getReferenceById 비교

구분findByIdgetReferenceById
데이터베이스 조회 시점즉시 조회사용 시점에서 조회 (Lazy)
반환 타입Optional<T>실제 엔티티(프록시 객체)
데이터가 없을 경우Optional.empty() 반환EntityNotFoundException 발생
주요 사용 목적데이터가 즉시 필요할 때참조만 필요하고 나중에 조회할 때

4. 언제 어떤 메서드를 사용해야 할까?

findById를 사용해야 할 때

  • 엔티티를 즉시 조회하고 사용할 때
  • 데이터가 없을 경우를 고려하여 Optional을 활용하고 싶을 때
  • 데이터가 항상 존재해야 하는 비즈니스 로직이 있을 때

getReferenceById를 사용해야 할 때

  • 엔티티의 ID만 필요하거나, 지연 로딩을 활용할 때
  • JPA 연관 관계에서 프록시 객체를 활용할 때
  • 엔티티가 실제로 사용되기 전까지 데이터베이스 조회를 피하고 싶을 때

5. 정리

  • findById는 즉시 조회하는 방식으로, 실제 데이터를 Optional<T>로 감싸서 반환한다
  • getReferenceById는 프록시 객체를 반환하며, 실제 데이터가 필요할 때 조회가 발생한다.
  • 트랜잭션 내에서 참조만 필요하거나, 연관 관계를 지연 로딩하는 경우 getReferenceById를 활용하면 성능을 최적화가 가능하다.

0개의 댓글