Member와 Team이 1:N관계라고 할 때
Member member = em.find(Member.class, 1L);
위 로직이 실행되면 어떻게 될까?
만약 Lazy 로딩을 사용하였다면
Team team = member.getTeam().getName();
member에서 team의 변수 값을 찾을 때 쿼리문이 나가게 된다.
team을 단순히 getTeam할 때는 프록시 객체가 반환된다.
Eager Loading(즉시)을 사용해서 member를 find할 때 Team의 값도 받아오도록한다. 쿼리문이 member를 조회할 때 Team과 join이 걸려서 나가게 된다.
즉시 로딩은 JPQL에서 N + 1 문제를 일으킬 수 있다.
JPQL을 사용 하여서 아래 쿼리문을 사용했다고 생각해보자.
select * from member
JPQL은 기본적으로 요청한 쿼리문을 실행하기 때문에 첫번 째에는 select * from member 쿼리문을 db에 요청하게 된다. 하지만 요청한 뒤에 Team Eager 로딩 전략을 사용하는 것을 확인한 다음 다시 team에서 where teamId = ? 조건으로 다시 쿼리요청하게 된다. 만약에 이것이 OneToMany 관계일 경우 team을 한번 호출 했을 때 member의 수(n)번만큼 다시 실행하게 된다. 따라서 DB가 죽는 원인이 될 수 있다.
실무에서는 모든 연관 관계에서 지연 로딩을 사용하여야 한다.
즉시 로딩은 상상하지 못한 쿼리가 나갈 수 있다.