인프런 커뮤니티 질문&답변

수빈님의 프로필 이미지
수빈

작성한 질문수

실전! Querydsl

조인 - 페치 조인

fetchjoin 미적용 쿼리

작성

·

29

0

@PersistenceUnit
    EntityManagerFactory emf;

@Test
public void fetchJoinNo() {
    em.flush();
    em.clear();

    Member findMember = queryFactory.selectFrom(member).where(member.name.eq("kim")).fetchOne();


    boolean loaded = emf.getPersistenceUnitUtil().isLoaded(findMember.getCart());
    assertThat(loaded).as("패치조인미적용").isFalse();

}

// select
//       m1_0.member_id,
//        m1_0.city,
//        m1_0.street,
//        m1_0.zipcode,
//       m1_0.cart_id,
//        m1_0.member_login_id,
//        m1_0.member_login_pw,
//        m1_0.name 
//    from
//        member m1_0 
//    where
//        m1_0.name=?
 
// -> 분명히 fetch join 미적용인데 select 절에 연관 entity 가 같이 조회되는 이유를 모르겠습니다. 현재 Cart 엔티티는 member 와 @OneToOne 관계이고 @FetchJoin.LAZY 로 설정되어 있습니다.

답변 2

0

안녕하세요. 수빈님, 공식 서포터즈 y2gcoder입니다.

이해를 하기 위해 조금 더 질문을 드리고 싶습니다!

제가 봤을 때는 보여주신 쿼리에서 from 절에 member 만 있고, join 절이 존재하지 않는데 어떤 점에서 연관 엔티티가 같이 조회되었다고 생각하십니까?

혹시 cart_id를 말씀하신 거라면 oneToOne 관계의 연관관계 주인이 member라서 member 에 대응하는 테이블에 cart_id라는 필드가 외래키로 있어 같이 조회되는 것이 아닌가 생각했습니다!

감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다.

수빈님께서 문의하신 내용과 관련하여 아래와 같은 설명을 드리겠습니다.

페치 조인을 사용하지 않고 연관 엔티티가 로드되는 이유는 다음과 같은 요소들을 고려해 볼 수 있습니다.

  1. 지연 로딩 설정 확인: @OneToOne 또는 @ManyToOne 관계에서 @FetchJoin.LAZY와 같은 설정이 제대로 적용되었는지 확인해야 합니다. 기본적으로 지연 로딩으로 설정되어 있다면, 기본적으로 해당 엔티티는 실제 사용될 때 데이터베이스에서 로드되어야 합니다.

  2. Hibernate의 강제 로딩: 때로는 Hibernate가 성능 최적화를 위해 필요하다고 판단하여 연관 엔티티를 강제로 로드할 수 있습니다. 특히 단일 엔티티를 조회할 때 이를 확인해 보실 수 있습니다.

  3. JPQL과 SQL 변환: JPQL로 쿼리를 전환할 때 내부적으로 엔티티 관계 설정에 의해 즉시 로딩이 적용되었을 가능성도 있습니다. JPQL에서의 join fetch가 명시적으로 없는 상태에서 엔티티의 연관 관계가 로드되었다면, 이는 Hibernate가 내부적으로 최적화를 적용했을 수 있습니다.

관련 내용을 더 깊이 이해하기 위해 다음의 게시물을 참조하시면 도움이 될 것입니다:

이 게시물들은 JPA와 Hibernate의 동작 원리에 대해 더 이해하는 데 유용할 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

수빈님의 프로필 이미지
수빈

작성한 질문수

질문하기