public interface MemberReposiotry extends JpaRepository<Member,Long> {
//Spring Data JPA로 Fetch Join 구현 1
@Query("select m from Member m left join fetch m.team")
List<Member> findMemberFetchJoin();
//이 방법만으로도 충분히 fetch join을 간편하게 구현이 가능하나,
//Spring Data JPA는 [@EntityGraph]를 이용하여, 기존과 같이 쿼리 메서드 명으로 fetch join을 구현하는 기능을 지원한다.
//Spring Data JPA로 Fetch Join 구현 2
@EntityGraph(attributePaths = {"team"} ) // Member -> Team ( 다 : 1 && 단방향 ) 관계이며, Member가 연관 관계의 주인이다.
@Override // JpaRepository 공통 인터페이스에는 이미 findAll()이 있으므로, 쿼리 메서드 기능을 이용하기 위해서는 오버라이딩을 해야 한다.
List<Member> findAll(); // Member를 조회할 때, (N+1) 문제를 @EntityGraph(attributePaths = {"team"} )이 해결!!!
//attributePaths = {"team"}는 Member를 조회할 때, Member와 연관 관계에 있는 엔티티 중 어떤 엔티티를 함께 fetch join 해올것인지를 지정
//Spring Data JPA로 Fetch Join 구현 3
@EntityGraph("Member.all")
@Query("select m from Member m")
List<Member> findMemberEntityGraph(); // 참고로, 이 메서드 명은 Spring Data JPA의 쿼리 메서드의 형식을 지키고 있지 않기에 쿼리 메서드 기능은 사용 X
//Spring Data JPA로 Fetch Join 구현 4
@EntityGraph(attributePaths = {"team"})
List<Member> findEntityGraphByUsername(@Param("username") String username); //이건 쿼리 메서드 기능을 사용하고 있다.
@Test@Transactional
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);
repository.save(new Member("member1", 10, teamA));
repository.save(new Member("member2", 20, teamB));
entityManager.flush();
entityManager.clear();
//when
List<Member> members = repository.findAll(); // @EntityGraph(attributespath = {"team}으로 (n+1) 문제 해결!
//then
for (Member member : members) {
member.getTeam().getName();
}
실무 팁
-> 간단 간단한 fetch join JPQL문 같은 경우에는 @EntityGraphy을 사용하면 되고
복잡한 fetch join JPQL의 경우는, 순수 JPQL로 직접 Fech join JPQL문을 짜면 된다.
'CS 잡지식' 카테고리의 다른 글
Dirty Checking의 치명적인 Weakness(단점)(feat. hint,lock) (1) | 2023.05.12 |
---|---|
SELECT ~~ FOR UPDATE(Feat. Concurrency Problem ) (0) | 2023.05.12 |
Spring Data JPA가 제공하는 막강한 [페이징],[정렬] (1) | 2023.05.12 |
Paging에서의 offset과 limit의 정확한 의미!! (0) | 2023.05.11 |
JPA 스펙 - 반환 타입 List,단건,Optional<단건 엔티티> (0) | 2023.05.11 |