• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

fetch join vs join

20.05.04 21:14 작성 조회수 733

3

안녕하세요 선생님 오랫만에 질문 다시 올립니다.이번강의도 정말 잘 듣고 있습니다. 아래와 같이 2가지의 다른 방식으로  queyrdsl를 사용하면  나가는 쿼리는 동일합니다.

하지만  jpa 에서 처리하는 방식이 다른거죠?  fetch join을 사용하면 LAZY까지  초기화 해서 한 객체를 만들어주고 다른 방식은 그냥 다른 두 객체로써 가지고 오는거죠?

  Member findMember = queryFactory

                .selectFrom(member)

                .join(member.team,team).fetchJoin()

                .where(member.username.eq("member1"))

                .fetchOne();

  Tuple findMember2 = queryFactory

                .select(member,team)

                .from(member)

                .join(member.team,team)

                .where(member.username.eq("member1"))

                .fetchOne();

 select

            member0_.member_id as member_i1_1_0_,

            team1_.team_id as team_id1_2_1_,

            member0_.age as age2_1_0_,

            member0_.team_id as team_id4_1_0_,

            member0_.username as username3_1_0_,

            team1_.name as name2_2_1_ 

        from

            member member0_ 

        inner join

            team team1_ 

                on member0_.team_id=team1_.team_id 

        where

            member0_.username=?

select

            member0_.member_id as member_i1_1_0_,

            team1_.team_id as team_id1_2_1_,

            member0_.age as age2_1_0_,

            member0_.team_id as team_id4_1_0_,

            member0_.username as username3_1_0_,

            team1_.name as name2_2_1_ 

        from

            member member0_ 

        inner join

            team team1_ 

                on member0_.team_id=team1_.team_id 

        where

            member0_.username=?

답변 2

·

답변을 작성해보세요.

8

안녕하세요. asdkfur님 오랜만입니다^^

fetch join이라는 기능 자체의 핵심은 연관된 엔티티를 한번에 최적화해서 조회하는 기능입니다. 그래서 LAZY가 발생하지 않습니다.

1. findMember.getTeam().getName() -> LAZY 쿼리 발생X

반면에 2번은 LAZY 상태를 유지하고 조회하기 때문에 LAZY 쿼리가 발생할 수 있습니다.

2. findMember2.getTeam().getName() -> LAZY 쿼리 발생O

그런데! 아마 실행해보시면 2번에서 LAZY 쿼리가 발생하지 않을꺼에요^^ 왜냐하면 2번에서 team을 결국 찾아야 하는데, JPA에서 LAZY 동작방식은 먼저 영속성 컨텍스트에 있는 team을 찾고 그래도 없으면 db에서 team을 찾게 됩니다. 그런데 2번에서 이미 team도 함께 select 절에서 찾아왔기 때문에 team이 영속성 컨텍스트에 존재하고, 따라서 쿼리 없이 함께 조회가 될꺼에요.

이번 예제가 좀 특수한 경우고, 일반적으로 team이 영속성 컨텍스트에 미리 존재하는 경우는 드물기 때문에, 대부분은 LAZY 호출시에 추가 쿼리가 발생합니다.

감사합니다.

3

asdkfur님의 프로필

asdkfur

질문자

2020.05.05

감사합니다 !