ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • #Spring Data JPA - 8 쿼리메소드 -@EntityGraph
    Spring Data JPA 2021. 3. 24. 16:12

    @EntityGraph

    (SPRING DATA JPA에서 fetchJoin을 편리하게 새용하기 위해쓰임)

     

    연관된 엔티티들을 SQL 한번에 조회하는 방법

     

    member →  team은 지연로딩 관계이다.

    따라서 다음과 같이 team의 데이터를 조회할 때 마다 쿼리가 실행된다. (N+1 문제 발생)

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

    forEach로 member만 가져올경우 select 절 한번으로 끝나지만 team을 가지고 올경우에는?

    member쿼리 한번 나가고 team을 찍을려고하니깐 PROXY객체여서 TEAM을 DB에서 가져온다.

    member만 가져올경우

    참고: 다음과 같이 지연 로딩 여부를 확인할 수 있다

     

    //Hibernate 기능으로 확인
    Hibernate.isInitialized(member.getTeam())
    
    //JPA 표준 방법으로 확인
    PersistenceUnitUtil util =
    em.getEntityManagerFactory().getPersistenceUnitUtil();
    util.isLoaded(member.getTeam());

    연관된 엔티티를 한번에 조회하려면 페치 조인이 필요하다

     

    JPQL 페치 조인

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

    스프링 데이터 JPA는 JPA가 제공하는 엔티티 그래프 기능을 편리하게 사용하게 도와준다.

    이 기능을 사용하면 JPQL 없이 페치 조인을 사용할 수 있다. (JPQL + 엔티티 그래프도 가능)

     

    EntityGraph(내부적으로 fetchjoin을 하는 것)

    //공통 메서드 오버라이드
    @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(@Param("username") String username)
    

    EntityGraph 정리

    · 사실상 페치 조인(FETCH JOIN)의 간편 버전

    · LEFT OUTER JOIN 사용

     

    NamedEntityGraph 사용 방법

    @NamedEntityGraph(name = "Member.all" //맴버 전체를 가지고올것
    			, attributeNodes = @NamedAttributeNode("team"))
    @Entity
    public class Member {}
    @EntityGraph("Member.all")
    @Query("select m from Member m")
    List<Member> findMemberEntityGraph();

     

    댓글

Designed by Tistory.