JPA

3. Eager, Lazy Loading

ggomjiu 2025. 6. 6. 18:48

- Spring Data JPA에 @ManyToOne(N : 1)으로 연관관계가 설정되어 있는 2개의 Entity가 존재할 때, DB는 join이 필요함

- @ManyToOne의 경우, FK 쪽의 Entity를 가져올 때, PK 쪽 Entity도 가져오게 되는데, 실무에서는 서비스의 규모가 대부분 크리 때문에 연관된 데이터를 한 번에 가져오는 행동은 부담이 큼

- JPA는 참조하는 데이터를 가져오는 시점을 정할 수 있는데, 이것을 Fetch Type이라고 함

 

Fetch Type

: JPA가 하나의 Entity를 조회할 때, 연관 관계에 있는 개체들을 어떻게 가져올 것이냐를 나타내는 설정값

- JPA에서는 JPQL을 이용하여 쿼리문을 생성하기 때문에 객체와 필드를 보고 쿼리를 작성함

- 다른 객체와 연관관계 매핑이 되어있으면, 그 객체들까지 조회하게 되는데, 이때 이 객체를 어떻게 불러올 것인가를 설정할 수 있음

 

Eager Loading(즉시 로딩)

: 특정 엔터티를 조회할 때, 연관된 모든 엔터티를 join을 통해 함께 조회하는 방식

- 엔터티 A조회시 관련되어 있는 엔터티 B를 같이 가져옴

- 실제 엔터티를 매핑함

- join을 사용하여 한 번에 가져옴 (즉시 로딩은 항상 외부 조인을 사용함)

- 장점 )

  • 지연된 초기화와 관련해서 성능적인 영향이 없음
  • 연관된 엔터티를 모두 가져올 수 있음

- 단점 )

  • 지연 로딩보다 긴 초기의 로딩 시간이 필요
  • 불필요한 데이터를 많이 로딩하면 성능에 영향을 줄 수 있음
  • JPQL에서는 N + 1 문제를 일으킴

Lazy Loading(지연 로딩)

: 자신과 연관된 엔터티를 실제로 사용할 때 연관된 엔터티를 조회하는 방식

- 엔터티 A를 조회시, 관련되어 있는 엔터이 B를 가져오지 않음

- 프록시 매핑을 하고 실제 B를 조회할 때 뭐리가 나감

- 쿼리가 2번 나감 (A 조회시 한 번 + B 조회시 한 번)

- 프록시 : 실제 객체의 상속본

- 지연 로딩을 하면 연결된 다른 엔터티의 값을 가져올 수 없음

- 이러한 문제를 해결하기 위해서는 DB와의 재연결이 필요한데, @Transactional 어노테이션을 통해 해결할 수 있음

- @Transactional : 해당 메소드를 하나의 트랜잭션으로 처리하라는 의미

- 트랜잭션으로 처리하면 속성에 따라 다르게 동작하지만, 기본적으로는 필요할 때 다시 DB와의 연결이 생성되기 때문에 정상적으로 실행이 됨

- 장점 )

  • 다른 접근 방식보다 훨씬 적은 초기의 로딩 시간
  • 다른 접근 방식에 비해 메모리 소비량 감소
  • 요청된 경우에만 사용자에게 콘텐츠를 제공하여 대역폭을 절약

- 단점 )

  • 초기화가 지연되면 원하지 않는 순간 성능에 영향을 줄 수 있음
  • DB와 연결된 Connection이 없다는 오류가 나타날 수 있음 -> 커넥션에 커밋을 날리고 트랜잭션이 닫힌 것을 의미