노트

지연 로딩

Lazy Loading

백엔드#jpa · 연결된 개념 12개

쉽게 말하면

지연 로딩은 사진 앱이 목록엔 자리만 잡아 두고, 사진을 실제로 눌러 볼 때 그제야 원본을 내려받는 방식이에요. 연관 데이터를 실제로 건드릴 때 DB에서 가져오니 안 쓸 데이터를 미리 안 불러와요.

비유가 깨지는 곳 목록을 넘기며 사진을 하나씩 다 열면 장마다 내려받듯 행마다 SELECT가 나가는 N+1이 생겨요. 영속성 컨텍스트가 닫힌 뒤 처음 열면 LazyInitializationException이 나니 필요한 곳은 fetch join으로 함께 가져와요.

연관된 엔티티를 처음 접근할 때 조회하는 방식. 그 전까지는 그 자리에 프록시(컬렉션이면 Hibernate 컬렉션 래퍼)가 들어 있다.

  • 목록을 돌면서 연관 필드를 건드리면 행마다 SELECT가 나간다 → N+1 문제
  • 영속성 컨텍스트가 닫힌 뒤 처음 접근하면 LazyInitializationException이 난다. OSIV (Open Session In View)를 켜 두면 컨트롤러·뷰까지 열려 있어 이 예외가 가려진다
  • 관계별 기본값은 아래와 같다. 기본이 즉시 로딩(eager loading, EAGER)인 ToOne 관계에도 fetch = FetchType.LAZY를 명시해 모두 LAZY로 두고, 필요한 곳에서 함께 가져온다
관계기본 FetchType
@ManyToOneEAGER
@OneToOneEAGER
@OneToManyLAZY
@ManyToManyLAZY

관계 매핑 전반은 JPA 연관관계 매핑, 함께 가져오는 쿼리는 fetch join을 본다.

책: 7장. 영속성 컨텍스트라는 출석부

출처: Hibernate ORM User Guide: Fetching · Best practices: Fetching associations

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 이미지 로딩 우선순위(loading·fetchpriority)

    loading은 이미지를 언제 받을지(lazy·eager)를, fetchpriority는 받을 때 얼마나 급한지(high·low·auto)를 브라우저에 알려 주는 HTML(HyperText Markup Language) 속성이다. 둘 다 LCP(Largest Contentful Paint)에 직접 영향을 준다.

  • Spring Data 리포지터리와 쿼리 메서드

    Spring Data는 인터페이스만 선언하면 구현체를 런타임에 만들어 주는 영속성 추상화(persistence abstraction)다. JpaRepository<엔티티, ID타입>을 상속하면 저장·조회·삭제·페이징이 바로 생기고, 메서드 이름 규칙만으로 쿼리를 만들 수도 있다.

  • JDBC와 JdbcTemplate

    JDBC(Java Database Connectivity)는 자바가 여러 DB와 통신하기 위한 표준 API이고, Hibernate·MyBatis·스프링 JDBC 모두 그 위에 있다. JdbcTemplate은 스프링이 JDBC의 반복 작업(연결 열고 닫기, 예외 변환, 결과 순회)을 대신해 주는 클래스다.

  • 페이지네이션 (offset·cursor)

    페이지네이션(pagination)은 큰 목록을 한 번에 다 주지 않고 조각으로 나눠 주는 방법이다. 크게 오프셋 방식(offset-based, 몇 번째부터 몇 개)과 커서 방식(cursor-based, 이 항목 다음부터 몇 개)으로 나뉜다.

  • 이미지 loading 속성

    img·iframe의 loading 속성으로 리소스를 언제 내려받을지 정한다. eager(기본)는 태그를 만나자마자, lazy는 화면에 가까워질 때까지 미룬다. JS(JavaScript) 없이 동작하는 브라우저 기본 기능이라 IntersectionObserver로 직접 만들 필요가 없다.

보기 옵션