코드 그라데이션

fetch join (페치 조인) (2) 컬렉션 페치 조인, DISTINCT 본문

Database/JPQL

fetch join (페치 조인) (2) 컬렉션 페치 조인, DISTINCT

완벽한 장면 2023. 9. 2. 14:16

컬렉션 페치 조인

 

실습

JpqlMain

public class JpqlMain {

  public static void main(String[] args) {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
    EntityManager em = emf.createEntityManager();

    EntityTransaction tx = em.getTransaction();
    tx.begin();

    try {
      Team teamA = new Team();
      teamA.setName("팀A");
      em.persist(teamA);

      Team teamB = new Team();
      teamB.setName("팀B");
      em.persist(teamB);

      Member member1 = new Member();
      member1.setUsername("회원1");
      member1.setTeam(teamA);
      em.persist(member1);

      Member member2 = new Member();
      member2.setUsername("회원2");
      member2.setTeam(teamA);
      em.persist(member2);

      Member member3 = new Member();
      member3.setUsername("회원3");
      member3.setTeam(teamB);
      em.persist(member3);


      em.flush();
      em.clear(); // 비움


      String query = "select t from Team t join fetch t.members";
      List<Team> result = em.createQuery(query, Team.class)
          .getResultList();
          
       System.out.println("result = " + result.size());    

      for (Team team : result) {
        System.out.println("team = " + team.getName() + ", 인원수 : "+ team.getMembers().size());
      }
      
     
  	  for (Member member : team.getMembers()) {
    	System.out.println(" -->  member = " + member);
  	}

      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      e.printStackTrace();
    } finally {
      em.close();
    }
    emf.close();
  }
}

 

실행하면

왜 중복으로 출력될까?

이 부분을 조심해야 한다.

 

DB입장에서는 일대다 조인하면 데이터가 뻥튀기 된다.

(팀 두 개밖에 없는데 result가 3으로 출력된 거에서 바로 확인 가능하죠.)

 

 

일대다 관계에서 DB쪽에서 다 가 뻥튀기

 


페치 조인과 DISTINCT

 

 

 

예시코드

 

distinct를 추가해

String query = "select distinct t from Team t join fetch t.members";
List<Team> result = em.createQuery(query, Team.class)
          .getResultList();
System.out.println("result = " + result.size());

for (Team team : result) {
  System.out.println("team = " + team.getName() + ", 인원수 : "+ team.getMembers().size());

	for (Member member : team.getMembers()) {
  		System.out.println(" -->  member = " + member);
	}

}

이렇게 바꾸고 실행을 해봤더니

 

신기하게도 중복이 제거된 채로 출력됨!

 

주의, 다대일 관계는 뻥튀기 안 된다.

 

 

 

 

 

728x90

'Database > JPQL' 카테고리의 다른 글

JPQL - 다형성 쿼리  (0) 2023.09.02
fetch join (페치 조인) (3) 페치 조인 vs 일반 조인, 페치 조인의 한계  (0) 2023.09.02
fetch join (페치 조인) (1) 기본  (0) 2023.09.02
경로 표현식  (0) 2023.09.01
JPQL 함수들  (0) 2023.09.01
Comments