JPA - JPQL 페치조인

bp.chys·2020년 6월 8일
1

JPA

목록 보기
10/15

페치 조인(Fetch Join)

  • JPQL에서 성능 최적화를 위해 제공하는 기능
  • 연관된 엔티티나 컬렉션을 SQL 한 번에 함께 조회할 수 있다.
  • join fetch

엔티티 페치 조인

  • @OneToOne, @ManyToOne
  • 회원을 조회하면서 연관된 팀도 함께 조회
// JPQL 
select m from Member m join fetch m.team

// SQL
select m.*, t.* from member m inner join team t on m.team_id = t.id

컬렉션 페치 조인

  • @OneToMany
  • 팀을 조회하면서 속한 회원 컬렉션을 함께 조회
  • 조인 테이블을 그대로 들고오기 때문에, 카테시안 곱으로 이름이 '팀A'인 컬렉션의 사이즈가 2가 되어버린다.
  • 이를 방지하기 위해서 t를 가져올 때 distinct로 가져온다.

String jpql = "select distinct t from Team t join fetch t.members where t.name = '팀A'"
List<Team> teams = em.createQuery(jpql, Team.class).getResultList();

for (Team team : teams) {
    System.out.println("teamname = " + team.getName() + ", team = " + team);
    for (Member member : team.getMemabers()) {
        // fetch join으로 조회했기 때문에 지연로딩 발생 하지 않음.
        System.out.println(" -> username = " + member.getUsername() + ", member = " + member);
     }
 }

페치 조인과 DISTINCT

  • SQL의 DISTINCT는 중복된 결과를 제거하는 명령
  • JPQL의 DISTINCT는 2가지 기능 제공
    • SQL에 DISTINCT를 추가 ← 하지만 조인 테이블은 완벽하게 모든 컬럼 값이 같지 않으므로 중복제거 실패한다.
    • 애플리케이션(영속성 컨텍스트)에서 엔티티 중복 제거

페치 조인의 한계

  • 페치조인 대상에는 별칭을 줄 수 없다.
  • 둘 이상의 컬렉션은 페치 조인을 할 수 없다.
  • 컬렉션을 페치조인하면 페이징 API를 사용할 수 없다.
  • 페치 조인은 객체 그래프를 유지할 때 사용하면 효과적이지만, 모든 것으르 페치조인으로 해결할 수는 없다.
  • 여러 테이블을 조인해서 엔티티가 가진 모양이 아닌 전혀 다른 결과를 내야 하면, 페치 조인 보다는 일반 조인을 사용하고 필요한 데이터들만 조회해서 DTO로 반환하는 것이 효과적이다. (프로젝션)

참고자료

  • 자바 ORM 표준 JPA 프로그래밍, 김영한 저
profile
하루에 한걸음씩, 꾸준히

0개의 댓글