공부

[JPA] FetchType 정리

SunYerim 2025. 3. 27. 14:45

FetchType

  • JPA에서 엔티티를 조회할 때 연관된 ‘엔티티 조회 방법을 결정하는 전략’
  • A와 B라는 엔티티가 존재한다고 했을때, 테이블 간의 관계에서 A엔티티를 조회하였을 경우 B엔티티를 함께 조회할 것인지 아니면 필요에 따라 조회할 것인지 결정하는 데 사용됨.
  • 지연 로딩의 관계에서는 A엔티티를 조회할 때 B엔티티는 조회하지 않고 B엔티티 데이터가 실제로 사용될 때 해당 데이터를 조회함.

FetchType.EAGER (즉시로딩)

  • 엔티티를 조회하는 방법을 정의하는 전략 중 하나.
  • 테이블 간의 관계에서 A라는 엔티티를 조회할 때 연관된 B라는 엔티티도 함께 조회하는 방식
  • 한번의 쿼리로 필요한 모든 데이터를 가져올 수 있으나 필요하지 않은 데이터까지 조회되어 성능 이슈 발생 가능.
  • 연관된 엔티티를 실제로 사용할 때 조회하는 방식이므로 엔티티를 조회할 때 연관된 엔티티도 함께 조회하여 메모리에 로드함.
  • ex. 유저 : 주문 → 1 : 다 관계에서의 유저 조회 결과
    • LEFT JOIN이 되어 유저 엔티티 값이 모두 출력됨

FetchType.LAZY (지연로딩)

  • 엔티티를 조회하는 방법을 정의하는 전략 중 하나
  • 테이블 간의 관계에서 A라는 엔티티를 조회할 때 연관된 B라는 엔티티도 있지만 A라는 엔티티만 조회하는 방식
  • 한번에 모든 데이터를 가져오지 않아 불필요한 데이터를 가져오는 것을 방지하여 성능을 향상할 수 있음.
  • ex. 유저 : 주문 → 1 : 다 관계에서의 유저 조회 결과
    • 주문 엔티티의 값을 불러오지 않고 유저엔티티에 대해서만 값이 출력됨.

Lazy Loading 원리

프록시 패턴

  • 실 객체를 대신하여 대리 객체(Proxy Object)를 생성하여 사용하는 디자인 패턴

프록시 패턴 처리과정

  • Subject(인터페이스), RealSubject(구현체), Proxy(대행자)로 구성.

  • Subject: RealSubject, Proxy에 대한 공통 인터페이스로 사용됨.

  • RealSubject의 일을 Proxy가 위임받아서 처리를 수행함.

  • Client → Subject

    • Subject 인터페이스는 RealSubject와 Proxy가 공통으로 구현해야 하는 인터페이스로 구성.
    • 클라이언트는 이 인터페이스에 접근하여 DoAction()이라는 메서드를 포출
  • RealSubject(implements) → Subject

    • Subject의 구현체인 RealSubject 클래스는 비즈니스 로직이 포함되어 있음.
    • 클라이언트가 호출한 DoAction() 메서드의 구현 부분이 이 클래스에 포함되어 있음.
  • Proxy → Subject

    • Proxy는 RealSubject의 대리자 역할을 함.
    • 클라이언트가 메서드를 호출하면 Proxy는 필요에 따라 이 요청을 RealSubject에 전달하거나, 결과를 반환하거나, 그 밖의 다양한 작업을 수행함.
    • 이를 통해 객체 생성 시점 제어, 접근 제어, 부가적인 로직 추가 등의 작업 수행 가능
  • Client → Subject 인터페이스의 DoAction()이라는 메서드를 호출. 해당 호출에서는 실 객체를 사용하지 않기 때문에(Lazy Loading) 이에 따르는 구현체인 RealSubject 클래스의 DoAction() 메서드가 수행되는 것이 아닌 Proxy가 이를 위임 받아서 DoAction()을 수행함.

프록시 객체

  • 실제 객체를 대신하여 사용되는 객체
  • 실제 객체와 같은 인터페이스를 가지고 있으므로, 실제 객체와 동일하게 사용 가능.
  • 실제 객체의 생성 시점을 제어하는 데 사용되며, 이는 지연 로딩의 핵심 원리. 실제 객체가 필요하기 전까지 실제 객체 생성을 지연함.
  • JPA에서는 엔티티를 프록시로 로딩하는 기능을 제공. @ManyToOne, @OneToOne 등의 연관관계에서는 FetchType을 LAZY로 설정하면, 연관된 엔티티를 프록시 객체로 로딩하고, 실제 엔티티가 필요한 시점에 데이터베이스에서 조회함.
  • 프록시 객체를 이용함으로써 실제 객체의 생성 시점을 제어하고, 불필요한 데이터베이스 조회를 줄여 성능을 향상할 수 있음.

참고자료

https://ko.wikipedia.org/wiki/%ED%94%84%EB%A1%9D%EC%8B%9C_%ED%8C%A8%ED%84%B4

'공부' 카테고리의 다른 글

[JPA] JPA의 N + 1 문제 정리  (0) 2025.03.27
JDBC, JPQL, QueryDSL etc  (0) 2025.03.27