@EntityGraph

Mina Park·2022년 10월 9일
0
  • 연관된 엔티티들을 한 번에 조회하는 방법

1. 지연로딩으로 인한 N+1 문제 발생

  • member -> team(LAZY)
  • 1(member 조회) + N(member 수만큼 team 조회) 쿼리 실행
@Test
public void findMemberLazy() throws Exception {
  //given
  //member1 -> teamA
  //member2 -> teamB
  Team teamA = new Team("teamA");
  Team teamB = new Team("teamB");
  teamRepository.save(teamA);
  teamRepository.save(teamB);
  memberRepository.save(new Member("member1", 10, teamA));
  memberRepository.save(new Member("member2", 20, teamB));
  em.flush();
  em.clear();
  
  //when
  List<Member> members = memberRepository.findAll();
  
  //then
  for (Member member : members) {
  	member.getTeam().getName();
  }
}

2. 연관된 엔티티를 한 번에 조회하기 위해 페치조인 적용

  • JPQL 페치조인
    • 그렇다면 페치조인을 이용하려면 무조건 JPQL을 써야하는걸까?
    • spring data jpa는 jpa가 제공하는 엔티티그래프 기능을 편리하게 사용하도록 도와줌
      • JPQL 없이도 페치조인 사용 가능
      • JPQL + 엔티티그래프 사용도 가능
@Query("select m from Member m left join fetch m.team")
List<Member> findMemberFetchJoin();

3. EntityGraph

  • 사실상 페치조인의 간편 버전과 같음
  • 기본적으로 LEFT OUTER JOIN 사용
//공통 메서드 오버라이드
@Override
@EntityGraph(attributePaths = {"team"})
List<Member> findAll();

//JPQL + 엔티티 그래프
@EntityGraph(attributePaths = {"team"})
@Query("select m from Member m")
List<Member> findMemberEntityGraph();

//메서드 이름으로 쿼리에서 특히 편리
@EntityGraph(attributePaths = {"team"})
List<Member> findByUsername(String username)

4. NamedEntityGraph

@NamedEntityGraph(name = "Member.all", attributeNodes =
@NamedAttributeNode("team"))
@Entity
public class Member {}
@EntityGraph("Member.all")
@Query("select m from Member m")
List<Member> findMemberEntityGraph();
    select
        member0_.member_id as member_i1_0_0_,
        team1_.team_id as team_id1_1_1_,
        member0_.age as age2_0_0_,
        member0_.team_id as team_id4_0_0_,
        member0_.username as username3_0_0_,
        team1_.name as name2_1_1_ 
    from
        member member0_ 
    left outer join
        team team1_ 
            on member0_.team_id=team1_.team_id

0개의 댓글