[JPA] 즉시로딩(LAZY), 지연로딩(EAGER)

2021. 10. 3. 21:14[ 백엔드 개발 ]/[ Spring ]

프록시 객체

- JPA에서 프록시 객체는 객체 탐색을 자유롭게 하기 위해서 필요한 시점에 쿼리를 날려 Entity화 하는 기술이다.

- JPA는 프록시 객체라는 기술을 이용해 연관된 객체를 처음부터 데이터베이스에서 조회하지 않고, 실제 사용하는 시점에 SELECT 쿼리를 통해 조회할 수 있다.

- JPA는 연관된 객체를 가져오는 시점에 따라 지연로딩(LAZY), 즉시로딩(EAGER) 두 가지 옵션을 제공하며 연관관계 매핑 어노테이션에서 FetchType 옵션을 통해 설정할 수 있다.

 

 

 

즉시로딩(EAGER), 지연로딩(LAZY)

 

김영한의 JPA 

 

1. 지연로딩(LAZY)

1) find 등을 통해 Member 엔티티를 가져온다. 그러면 그 안에 주문리스트가 있을 것이고, 주문리스트는 프록시 객체로 저장되어 있다.

2) 그 후에 주문리스트.get(0) 등과 같이 주문리스트의 상태를 조회하는 등의 작업으로 주문리스트를 사용할 때, 프록시 객체가 영속성 컨텍스트에 초기화 요청을 보내고, 영속성 컨텍스트에서는 DB를 조회해 실질적인 주문리스트를 가져온다.

3) 영속성 컨텍스트에서 DB를 조회한 후 주문리스트를 Entity로 만들어 반환해준다.

4) 지연로딩의 장점 :

- 지연로딩 대상이 여러번 호출될 경우 1차캐시에 존재하게 되므로 N번 보내야 할 쿼리 횟수를 1번으로 줄일 수 있음. 즉, 연관된 객체는 사용하지도 않는데 굳이 쿼리를 날리게 된다는 단점을 해결

- join 연산 발생가능성을 줄임

 

 

2. 즉시로딩(EAGER)

find를 통해 Member 조회 시 주문리스트도 동시에 같이 가져오는 형태이다. 즉, 프록시 객체를 두지 않고 한번에 Member와 주문리스트를 엔티티화 시켜서 가져온다.

 

참조 객체와 항상 함께 로드되어야 하는 상황에서는 EAGER를 사용한다.

 

 

 

정리

JPA에서 테이블 간 연관 관계는 객체 참조를 통한 객체그래프를 통해 이루어진다. 참조하는 객체가 많아질수록, DB로부터 참조하는 객체들의 데이터까지 한꺼번에 가져오는 행동은 부담이 커질 수 있다. 따라서 Entity를 가져온 후에 이 Entity와 연관된 또 다른 Entity도 사용된다면 EAGER를 사용하는게 유리하지만, 그 외의 경우에는 LAZY를 기본적으로 사용한다.

 

EAGER type일 경우 연관된 Entity들을 한번에 가져와야 하기 때문에 JOIN연산이 수행되지만 LAZY type의 경우 단순한 쿼리를 통해 이루어지므로 성능적인 면에서도 LAZY type이 더욱 유리하다.