select m from Team t join t.members m -> 자동 fetch join되는 현상..??
81
작성한 질문수 17
안녕하세요. jpql을 다양하게 짜면서 나가는 sql이 어떻게 되는 지 학습하는 과정에서 질문이 생겨 글 남기게 됐습니다.
List<Member> resultList = em.createQuery("select m from Team t join t.members m", Member.class)
.getResultList();
for (Member member : resultList) {
System.out.println("member.getTeam() = " + member.getTeam().getClass());
}위와 같이 jpql을 짜면 fetch join이 아니라 일반 join임에도 불구하고 조회한 member들에 대해서 member.getTeam().getName()을 해도 추가 쿼리가 나가지 않습니다. 위의 코드처럼 member.getTeam().getClass()를 통해 확인해보니 아래처럼 결과가 나와 member의 team이 프록시객체가 아니라 실제객체라는 것을 확인할 수 있었습니다.
Hibernate:
/* select
m
from
Team t
join
t.members m */ select
m1_0.id,
m1_0.age,
t1_0.id,
t1_0.name,
m1_0.username
from
Team t1_0
join
Member m1_0
on t1_0.id=m1_0.TEAM_ID
member.getTeam() = class jpql.Team
member.getTeam() = class jpql.Team
member.getTeam() = class jpql.TeamfetchType을 분명히 lazy로 했음에도 불구하고 위의 결과처럼 member만을 조회했는데도 불구하고 team까지 조회하는 sql이 나가는 이유가 무엇인가요?
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
문예찬님, JPQL에서 일반 조인을 사용했음에도 불구하고 추가적인 SQL 쿼리가 나가지 않는 이유는 JPA의 엔티티 그래프를 로딩하는 방식에서 찾을 수 있습니다.
JPA에서는 엔티티를 조회할 때, 기본적으로 Eager Fetch인 경우에는 즉시 로딩하지만, Lazy Fetch인 경우에는 실제로 그 관계의 속성에 접근할 때 쿼리를 실행하여 데이터를 로딩합니다. 그러나 JPQL 쿼리에서 관련 엔티티가 함께 조인되어 조회될 때는, 이미 그 데이터가 사용 가능한 상태로 조회되며, 이 경우에는 추가적인 지연 로딩 쿼리가 필요 없이 메모리에 로드된 상태로 사용됩니다.
즉, JPQL 자체에서 일반 조인을 사용할 경우에도, 관련된 엔티티가 Eager 로딩으로 간주되어 추가 쿼리 없이 해당 엔티티들이 메모리에 로드됩니다. 따라서 member.getTeam()을 호출할 때 실제 객체가 반환되는 것이며, 이로 인해 프록시 객체가 아닌 실제 Team 객체의 클래스가 출력된 것입니다.
이 동작은 JPQL의 조인 최적화와 관련된 것으로, 기본적으로 세심한 엔티티 로딩을 조절하고 싶다면 @EntityGraph 등의 방법을 활용해 로딩 방식을 명시적으로 설정할 수 있습니다.
추가적인 정보는 스프링 데이터 JPA의 모델링 및 로딩 전략에서 얻으실 수 있습니다.
도움이 되었길 바랍니다. 좋은 학습 되세요!
벌크연산에서 member.getAge 호출 시 영속성 컨텍스트에서 데이터를 가져오는건가요?
0
32
2
inheritance startegy 선택시 고려사항
0
24
1
Entity 동등성 비교
0
23
1
실무 조언 관련 질문입니다.
0
48
1
H2데이터베이스 파일 생성
0
57
2
서브쿼리 강의에서 ALL 예시 관련 질문드립니다.
0
55
2
수정또는 삭제시 영속성 엔티티에 값이 무조건 있어야 하나요?
0
57
1
JPQL 메소드와 락
0
55
1
Delivery @OneToOne
0
61
1
17강 4~5분대 테이블 값 조회가 안됩니다.
0
96
2
UnsupportedOperationException 발생
0
86
3
H2 Database 연결이 안됩니다.
0
97
2
연관관계 매핑 질문드립니다.
0
86
2
h2데이터베이스 실행오류
0
108
2
persistence.xml
0
110
2
양방향 연관관계에서 연관관계의 주인(mappedBy)을 왜 꼭 정해야 하나요?
0
83
1
영속성 컨텍스트
0
69
1
JPA 프록시
0
98
1
Native Query와 MyBatis
0
71
1
영속성 컨텍스트는 어떤 메모리에 저장되는건가요?
0
89
1
임베디드 타입 예시 코드 관련 질문
0
119
3
명시적 조인에서 별칭을 주면 왜 객체에 접근할 수 있나요
0
96
3
인텔리제이 패키지 커서 단축키 질문
0
108
2
혹시 현재는 ID 데이터 타입이 String이면 안되나요?
0
149
1





