본문 바로가기

JPA

[JPA] 지연 로딩과 즉시 로딩

예를 들어 두 개의 엔티티 Member와 Team이 서로 연관관계에 있다고 가정하자

나는 Member만 조회하고 싶은데 Team과 연관 관계에 있다고 해서 같이 조회해야 할까?

만약 90퍼센트 이상이 Member를 조회할 때 Team도 조회해야 한다고 한다면 상관없겠지만 그렇지 않다면 굉장히 비효율 적일 것이다.

이것을 더 효율적으로 할 수 있는 것이 지연 로딩이다.

 

지연 로딩

연관관계 매핑할 때 fetch = FetchType.LAZY를 넣어주면 지연 로딩이 설정된다.

이렇게 하면 Team은 프록시 객체를 조회하게 되는데, 즉 Member클래스만 DB에서 조회하게 되는 것이다.

 

만약 Member와 Team의 연관관계 매핑 시 지연 로딩을 설정하지 않고 find를 통해서 Member를 조회하게 되면

원하지 않는 Team도 조회하게 된다.

 

지연 로딩으로 하고 똑같이 조회하게 되면

Team과 Join을 하지 않고 Member만을 찾는 쿼리가 나가게 된다.

 

이렇게 지연 로딩을 설정한 후에 Team은 어떻게 조회가 되는 것일까?

위에서 말했듯이 Team은 프록시 객체로 조회가 되는 것을 알 수 있다.

아직은 Team의 프록시를 가져오는 것이기 때문에 (m.getTeam) 이때 쿼리가 나가지 않고

m.getName()을 호출할 때 프록시를 가져와서 프록시의 어떤 메서드를 터치할 때 프록시의 내부의 값이 없기 때문에 초기화가 일어난다.

 

지연 로딩과 반대로 Member를 호출할 때 연관관계에 속해있는 것을 모두 가져오는 것을 '즉시 로딩'이라고 한다.

 

즉시 로딩

즉시 로딩은 fetch = FetchType.EAGER를 통해서 즉시 로딩으로 설정할 수 있게 되는데,

위에서 아무것도 설정해주지 않았을 때와 같이 find를 통해 Member를 찾는 코드를 실행했을 때

Team도 같이 조회되는 쿼리가 나간다.

 

그 이유는

@ManyToOne, @OneToOne은 기본이 즉시 로딩(FetchType.EAGER)이고

@OneToMany, @ManyToMany는 기본이 지연 로딩이기 때문이다.

 

그래서 만약 Member를 조회하면 Team도 같이 조회하는 경우가 대부분이라면 즉시 조회가 더 유리하겠지만

웬만하면 XToOne은 지연 로딩으로 설정해주는 것이 좋다.

 

모든 관계를 지연 로딩으로 설정하고 JPQL를 이용해서 Member와 Team을 조인해서 같이 알고 싶다면 fetch join을 이용해서 찾는 방법이 있다.

'JPA' 카테고리의 다른 글

[JPA] 페치 조인(fetch join)의 한계  (0) 2021.01.21
[JPA] 페치조인(fetch join)이란?  (0) 2021.01.21
[JPA] 프록시란?  (0) 2020.12.23
상속관계 매핑  (0) 2020.12.22
연관관계 매핑  (0) 2020.12.22