노트지연 로딩
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 |
|---|
@ManyToOne | EAGER |
@OneToOne | EAGER |
@OneToMany | LAZY |
@ManyToMany | LAZY |
관계 매핑 전반은 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로 직접 만들 필요가 없다.