[데이터베이스]/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
반응형