둘 다 "지연로딩(LAZY)을 우회해서 한 번에 가져오자"는 목적인데, 방식이 다름.
공통점
- LAZY로 설정된 필드도 미리 불러올 수 있다.
- 실제 SQL 쿼리에서는 JOIN으로 연관 엔티티 가져옴
- N+1 문제를 예방하는 데 사용됨
우선 가장 큰 차이점
간단하게 한 두개 엔티티 -> entity Graph가 괜찮음
-> 복잡하면 -> fetch join.
아마 실무에서 팀이 어떻게 하느냐에 맞추면 될듯
핵심 차이 요약표
fetch join EntityGraph
| 사용 위치 | JPQL 안에서 직접 명시 | 리포지토리 메서드 어노테이션으로 지정 |
| 쿼리 작성 방식 | 직접 쿼리 작성 (JOIN FETCH) | 쿼리는 그대로 두고, fetch 대상만 추가 지정 |
| 유연성 (WHERE 조건 등) | 매우 높음 (자유로운 조건 가능) | 낮음 (조건은 쿼리에만, fetch 대상만 지정) |
| JPQL SELECT 제어 | 가능 (SELECT new DTO(...)) | 제한적 (엔티티 단위만 가능) |
| 동작 시점 | JPQL 실행 시 바로 JOIN | EntityManager 내부에서 적용됨 |
| 쿼리 명시성 | 직접 확인 가능 | 내부적으로 숨겨져 있음 |
| 복잡한 fetch 조합 | 자유롭게 여러 JOIN 가능 (단, 1:N 중복 주의) | 중첩된 경로 제한 있음 |
| 직렬화 대상 제한 (REST API) | DTO 조합 유리 | 엔티티 리턴 시 순환참조 위험 있음 |
🔹 fetch join 예시
@Query("SELECT m FROM Member m JOIN FETCH m.orders WHERE m.name = :name")
Member findMemberWithOrders(@Param("name") String name);
- 완전한 제어 가능 (WHERE 절, SELECT 대상, 조건 필터링 등)
🔹 EntityGraph 예시
@EntityGraph(attributePaths = {"orders"})
@Query("SELECT m FROM Member m WHERE m.name = :name")
Member findMemberWithEntityGraph (@Param("name") String name);
- JPQL은 깔끔하게 유지하면서, fetch 대상만 따로 지정
'TIL' 카테고리의 다른 글
| UNDO 공간부족 오류란 (0) | 2025.05.20 |
|---|---|
| DB 마이그레이션 적용하는 법 (1) | 2025.05.20 |
| LazyInitializationException (0) | 2025.05.19 |
| Kotlin vs Java (0) | 2025.05.13 |
| 조인 vs 서브쿼리 (0) | 2025.05.13 |