문제상황
member와 team이 연관관계가 있는 경우→ member정보만 조회할 때 team도 조회해야하는가
Solution ] JPA 지연로딩
![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c5768cc2-4fd0-4771-872d-560c17052342/Untitled.png)
![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/dcfe45ec-8622-4298-95ed-c181e927632d/Untitled.png)
- 이렇게 선언할 경우, Team Type을 proxy객체로 리턴한다.
- 즉 team을 참조하는 시점에 proxy객체가 초기화 되면서 DB로 쿼리를 날리게 된다.
- 정확히는 getTeam()이 아닌 getTeam().getName() 즉, proxy객체의 메소드를 호출할 때 초기화된다.
![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/be5613a4-1f43-4809-a7b2-511f199b1617/Untitled.png)
JPA 즉시로딩 - EAGER
![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/36260dc0-a7c7-42aa-9dfe-f289e0ce9c01/Untitled.png)
- 이 경우, 즉시로딩 타입으로 적용되며 Member 조회 시 Member, Team을 조인하여 쿼리를 가져오게 된다.
- 즉 Team객체는 Proxy가 아닌 엔티티 객체를 반환한다.
🚨 프록시와 즉시로딩
- 지연로딩만 사용하자. Table을 수십개 조인하면 성능 문제가 심각하다.
- 즉시로딩을 적용할 경우 예상치못한 SQL이 발생한다
- 즉시로딩은 JPQL에서 N+1문제가 발생한다
- @ManyToOne, @OneToOne은 기본적으로 즉시로딩으로 설정되어있다. LAZY타입으로 지정해주자
- @OneToMany, @ManyToMany는 기본적으로 지연로딩이 설정되어있다.
📄N+1 문제란?
![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/bcad61b2-94b2-49d1-9f01-653e4e280d56/Untitled.png)
![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a69499a8-3994-4138-a0d6-bb268273c528/Untitled.png)
- JPQL은 쿼리문을 SQL로 번역하여 쿼리를 작성한다
- 즉, 위 코드에서 Member만 가져오므로 Team에 대한 의존성을 맞춰줄 수 없게된다.
- 따라서 이를 해결하기 위해, JPQL은 멤버의 개수만큼 Team을 select하는 쿼리가 날아가게 된다.
- 즉, 즉시로딩으로 타입을 지정하게 되는 경우 총 테이블의 row수인 N개만큼 team select 쿼리가 날아가므로 N+1개 만큼의 쿼리가 생성된다.