작성
·
207
0
@Test
public void fetchJoinNo() throws Exception{
em.flush();
em.clear();
/*Member findMember = queryFactory
.selectFrom(member)
.where(member.username.eq("member1"))
.fetchOne();*/
Tuple tuple= queryFactory
.select(member,team)
.from(member)
.where(member.username.eq("member1"))
.fetchOne();
String qlString= "select m,m.team from Member m where m.username=:username";
Tuple tuple1 = (Tuple) em.createQuery(qlString, Tuple.class).setParameter("username","member1")
.getResultList();
boolean loaded = emf.getPersistenceUnitUtil().isLoaded(tuple.get(team));
assertThat(loaded).as("페치 조인 적용").isTrue();
}
위 코드는 위 코드에서 tuple 을 이용해서 ,member 와 team 을 함꼐 조회해 보았을 때 team 이 영속화 되는지 실험한 것입니다.
아래 코드입니다.
queryFactory
.select(member,team)
.from(member)
.where(member.username.eq("member1"))
.fetchOne();
원래 fetchJoin() 을 안붙여서 안될 것이라고 생각했습니다만 의외로 되가지고 뭐지 ? 했습니다.
원래 되는 것인가요??
그러면 원래 이게 의미하는 JPQL 인
select
member1,
team
from
Member member1
where
member1.username = ?1
를 직접 작성하면
@Query("select m, m.team from Member m wherer m.username=:username)
뭐 이런식으로 해도 fetch join 이 된다는 얘기 아닌가요?
답변 2
0
0
안녕하세요, 인프런 AI 인턴입니다.
님의 질문에 대한 답변은 아래와 같습니다.
JPQL을 사용해서 쿼리를 작성할 때 페치 조인(fetch join)은 명시적으로 사용해야 합니다. 페치 조인을 사용하지 않는 경우, 연관된 엔티티는 지연 로딩(LAZY) 전략에 따라 로드되거나, 즉시 로딩(EAGER) 전략에 설정되어 있다면 같이 로드됩니다. 그러나 이 경우에는 페치 조인과는 다릅니다.
페치 조인을 사용하려면 JPQL에서 join fetch
구문을 사용해야 합니다. 예를 들어, Member
엔티티와 연관된 Team
엔티티를 페치 조인으로 가져오려면 다음과 같이 쿼리를 작성해야 합니다.
select m from Member m join fetch m.team where m.username = :username
페치 조인을 사용할 경우, 연관된 엔티티는 주 쿼리 실행 시 함께 로드되며, 결과적으로 N+1 문제를 방지할 수 있습니다. 데이터를 한 번의 쿼리로 가져오기 때문에 성능이 개선되는 장점이 있습니다.
따라서, 코드 예제에서 fetchOne()
을 사용하여 Member
와 Team
을 함께 조회했지만, 명시적으로 페치 조인을 사용하지 않았다면, 이는 페치 조인이 적용된 것이 아니라 연관된 엔티티가 다른 방식(예: 즉시 로딩)으로 로드된 것일 수 있습니다.
즉, 정확한 페치 조인의 적용 여부를 확인하려면 join fetch
나 @EntityGraph
등을 통해 명시적으로 페치 조인을 선언해야 합니다.