웹/Spring Data

[스프링 데이터 JPA] 5. EntityGraph

두잇베스트 2020. 12. 17. 14:29

EntityGraph

  • 스프링데이터 JPA에서는 페치 조인 2가지 방법을 이용할 수 있다. @Query 를 이용한 페치 조인과 EntityGraph 를 사용하는 것이다.

JPQL 페치 조인

@Query("select m from Member m join fetch m.team t")
List<Member> findMemberFetchJoin();

 

 

EntityGraph


  • 스프링 데이터 JPA 인터페이스를 오버라이드해서 사용
@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)

 

 

 

 

테스트 코드

@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);

    Member member1 = new Member("member1", 10, teamA);
    Member member2 = new Member("member2", 10, teamB);
    memberRepository.save(member1);
    memberRepository.save(member2);

    em.flush();
    em.clear();

    //when N + 1의 문
    List<Member> members = memberRepository.findEntityGraphByUsername("member1");
    for (Member member : members) {
        System.out.println("member = " + member.getUsername());
        System.out.println("member.teamClass = " + member.getTeam().getClass());
        System.out.println("member = " + member.getTeam().getName());
    }

    //then 
}

 

left outer join으로 페치 조인해서 잘 가져온다

페치 조인은 @OneToOne , @ManyToOne 지연 로딩에 의한 N+1 문제를 해결해준다. (이거에 대해서는 블로그에 나중에 쓰도록) . 페치 조인과 그냥 조인의 차이점은 select 절에 있다. 조인은 select한 필드만 가져오는데, 페치 조인 같은 경우 모든 필드(컬럼들을 가져온다)

 

정리

  • EntityGraph는 페치 조인의 간편하게 쓰기 위한 버전이다
  • Left Outer Join을 사용한다.

 

 

Reference