코드 그라데이션

즉시 로딩 본문

Spring/JPA 공부

즉시 로딩

완벽한 장면 2023. 8. 24. 13:39

Member와 Team을 자주 함께 사용한다면?

 

즉시 로딩 EAGER 를 사용해서 함께 조회

Member 엔티티 변경

 

즉시 로딩

 

즉시 로딩(EAGER), Member 조회 시 항상 Team도 조회.

 

 

JpaMain

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

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

    try {
      //팀도 세팅
      Team team = new Team();
      team.setName("teamA");
      em.persist(team);

      Member member1 = new Member();
      member1.setUsername("member1");
      member1.setTeam(team);
      em.persist(member1);

      em.flush();
      em.clear();

      Member m = em.find(Member.class, member1.getId());
      System.out.println("m = " + m.getTeam().getClass());

      System.out.println("이전===================");
//      m.getTeam().getName(); // 쿼리 나가는 시점(초기화) => 여기서는 필요x
      System.out.println("teamName = " + m.getTeam().getName()); // 실제 팀이름 teamA가 출력됨.
      System.out.println("이후===================");

      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      e.printStackTrace(); // 하나 찍어봄
    } finally {
      em.close();
    }
    emf.close();
  }
}

 

 

로그를 보면

11:46:58.366 [main] DEBUG org.hibernate.SQL - 

Hibernate: 
    select
        member0_.MEMBER_ID as member_i1_3_0_,
        member0_.createdBy as createdb2_3_0_,
        member0_.createdDate as createdd3_3_0_,
        member0_.lastModifiedBy as lastmodi4_3_0_,
        member0_.lastModifiedDate as lastmodi5_3_0_,
        member0_.TEAM_ID as team_id7_3_0_,
        member0_.USERNAME as username6_3_0_,
        team1_.TEAM_ID as team_id1_7_1_,
        team1_.createdBy as createdb2_7_1_,
        team1_.createdDate as createdd3_7_1_,
        team1_.lastModifiedBy as lastmodi4_7_1_,
        team1_.lastModifiedDate as lastmodi5_7_1_,
        team1_.name as name6_7_1_ 
    from
        Member member0_ 
    left outer join
        Team team1_ 
            on member0_.TEAM_ID=team1_.TEAM_ID 
    where
        member0_.MEMBER_ID=?
11:46:58.373 [main] DEBUG org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl - On call to EntityIdentifierReaderImpl#resolve, EntityKey was already known; should only happen on root returns with an optional identifier specified
11:46:58.376 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Resolving attributes for [inflearn.exjpa.jpaExample.Member#2]
11:46:58.376 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdBy` : value = null
11:46:58.376 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdBy`)  - enhanced for lazy-loading? - false
11:46:58.376 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdDate` : value = null
11:46:58.376 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdDate`)  - enhanced for lazy-loading? - false
11:46:58.376 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedBy` : value = null
11:46:58.376 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedBy`)  - enhanced for lazy-loading? - false
11:46:58.376 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedDate` : value = null
11:46:58.376 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedDate`)  - enhanced for lazy-loading? - false
11:46:58.376 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `memberProducts` : value = NOT NULL COLLECTION
11:46:58.376 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`memberProducts`)  - enhanced for lazy-loading? - false
11:46:58.377 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `team` : value = 1
11:46:58.377 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`team`)  - enhanced for lazy-loading? - false
11:46:58.377 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `username` : value = member1
11:46:58.377 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`username`)  - enhanced for lazy-loading? - false
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done materializing entity [inflearn.exjpa.jpaExample.Member#2]
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Resolving attributes for [inflearn.exjpa.jpaExample.Team#1]
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdBy` : value = null
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdBy`)  - enhanced for lazy-loading? - false
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdDate` : value = null
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdDate`)  - enhanced for lazy-loading? - false
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedBy` : value = null
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedBy`)  - enhanced for lazy-loading? - false
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedDate` : value = null
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedDate`)  - enhanced for lazy-loading? - false
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `members` : value = NOT NULL COLLECTION
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`members`)  - enhanced for lazy-loading? - false
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `name` : value = teamA
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`name`)  - enhanced for lazy-loading? - false
11:46:58.378 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done materializing entity [inflearn.exjpa.jpaExample.Team#1]
11:46:58.378 [main] DEBUG org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader - Done entity load : inflearn.exjpa.jpaExample.Member#2
m = class inflearn.exjpa.jpaExample.Team
이전===================
teamName = teamA // 진짜 이름!!!
이후===================

EAGER로 되어 있으면 두 가지 선택이 가능하다

 

 


** 프록시와 즉시 로딩 주의

 

 

JpaMain

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

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

    try {
      //팀도 세팅
      Team team = new Team();
      team.setName("teamA");
      em.persist(team);

      Member member1 = new Member();
      member1.setUsername("member1");
      member1.setTeam(team);
      em.persist(member1);

      em.flush();
      em.clear();

//      Member m = em.find(Member.class, member1.getId());
      List<Member> members = em.createQuery("select m from Member m", Member.class)
          .getResultList(); // 리스트로 members를 가져오기

      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      e.printStackTrace(); // 하나 찍어봄
    } finally {
      em.close();
    }
    emf.close();
  }
}

 

로그를 보면

12:18:12.270 [main] DEBUG org.hibernate.SQL - 

Hibernate: 
    /* select
        m 
    from
        Member m */ select
            member0_.MEMBER_ID as member_i1_3_,
            member0_.createdBy as createdb2_3_,
            member0_.createdDate as createdd3_3_,
            member0_.lastModifiedBy as lastmodi4_3_,
            member0_.lastModifiedDate as lastmodi5_3_,
            member0_.TEAM_ID as team_id7_3_,
            member0_.USERNAME as username6_3_ 
        from
            Member member0_
12:18:12.273 [main] DEBUG org.hibernate.loader.Loader - Result set row: 0
12:18:12.273 [main] DEBUG org.hibernate.loader.Loader - Result row: EntityKey[inflearn.exjpa.jpaExample.Member#2]
12:18:12.276 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Resolving attributes for [inflearn.exjpa.jpaExample.Member#2]
12:18:12.276 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdBy` : value = null
12:18:12.276 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdBy`)  - enhanced for lazy-loading? - false
12:18:12.276 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdDate` : value = null
12:18:12.276 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdDate`)  - enhanced for lazy-loading? - false
12:18:12.276 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedBy` : value = null
12:18:12.276 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedBy`)  - enhanced for lazy-loading? - false
12:18:12.276 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedDate` : value = null
12:18:12.276 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedDate`)  - enhanced for lazy-loading? - false
12:18:12.276 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `memberProducts` : value = NOT NULL COLLECTION
12:18:12.276 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`memberProducts`)  - enhanced for lazy-loading? - false
12:18:12.277 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `team` : value = 1
12:18:12.277 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`team`)  - enhanced for lazy-loading? - false
12:18:12.279 [main] DEBUG org.hibernate.SQL - 

Hibernate: 
    select
        team0_.TEAM_ID as team_id1_7_0_,
        team0_.createdBy as createdb2_7_0_,
        team0_.createdDate as createdd3_7_0_,
        team0_.lastModifiedBy as lastmodi4_7_0_,
        team0_.lastModifiedDate as lastmodi5_7_0_,
        team0_.name as name6_7_0_ 
    from
        Team team0_ 
    where
        team0_.TEAM_ID=?

즉시 로딩으로 설정했음에도 쿼리가 2번 나가고 있음.

 

em.find()는 PK를 찍어서 가져오기 때문에 JPA가 내부적으로 알아서 찾아서 다 할 수가 있다.

그런데 JPQL은 

select m from Member m

그대로 SQL로 번역된다. => 그럼 당연히 Member만 Select 한다는 뜻.

Member를 가져왔더니, 확인해보니까 Team이 EAGER로 되어 있네???

즉시로딩은 일단 가져올 때 값이 무조건 다 들어가 있어야 한다.

그럼 member가 10개라고 한다면 team을 가져오는 쿼리도 10번 나가야한다는 뜻.

 

개수를 더 늘려서 확인해보면

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

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

    try {

      Team team1 = new Team();
      team1.setName("teamA");
      em.persist(team1);

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

      Member member1 = new Member();
      member1.setUsername("member1");
      member1.setTeam(team1);
      em.persist(member1);

      Member member2 = new Member();
      member2.setUsername("member2");
      member2.setTeam(team2);
      em.persist(member2);


      em.flush();
      em.clear();

//      Member m = em.find(Member.class, member1.getId());
      List<Member> members = em.createQuery("select m from Member m", Member.class)
          .getResultList(); // 리스트로 members를 가져오기

      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      e.printStackTrace(); // 하나 찍어봄
    } finally {
      em.close();
    }
    emf.close();
  }
}

 

12:27:32.794 [main] DEBUG org.hibernate.SQL - 

Hibernate: 
    /* select // member가져온다.
        m 
    from
        Member m */ select
            member0_.MEMBER_ID as member_i1_3_,
            member0_.createdBy as createdb2_3_,
            member0_.createdDate as createdd3_3_,
            member0_.lastModifiedBy as lastmodi4_3_,
            member0_.lastModifiedDate as lastmodi5_3_,
            member0_.TEAM_ID as team_id7_3_,
            member0_.USERNAME as username6_3_ 
        from
            Member member0_
12:27:32.795 [main] DEBUG org.hibernate.loader.Loader - Result set row: 0
12:27:32.796 [main] DEBUG org.hibernate.loader.Loader - Result row: EntityKey[inflearn.exjpa.jpaExample.Member#3]
12:27:32.798 [main] DEBUG org.hibernate.loader.Loader - Result set row: 1
12:27:32.798 [main] DEBUG org.hibernate.loader.Loader - Result row: EntityKey[inflearn.exjpa.jpaExample.Member#4]
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Resolving attributes for [inflearn.exjpa.jpaExample.Member#3]
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdBy` : value = null
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdBy`)  - enhanced for lazy-loading? - false
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdDate` : value = null
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdDate`)  - enhanced for lazy-loading? - false
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedBy` : value = null
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedBy`)  - enhanced for lazy-loading? - false
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedDate` : value = null
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedDate`)  - enhanced for lazy-loading? - false
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `memberProducts` : value = NOT NULL COLLECTION
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`memberProducts`)  - enhanced for lazy-loading? - false
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `team` : value = 1
12:27:32.800 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`team`)  - enhanced for lazy-loading? - false
12:27:32.803 [main] DEBUG org.hibernate.SQL - 
Hibernate: // teamA
    select
        team0_.TEAM_ID as team_id1_7_0_,
        team0_.createdBy as createdb2_7_0_,
        team0_.createdDate as createdd3_7_0_,
        team0_.lastModifiedBy as lastmodi4_7_0_,
        team0_.lastModifiedDate as lastmodi5_7_0_,
        team0_.name as name6_7_0_ 
    from
        Team team0_ 
    where
        team0_.TEAM_ID=?
12:27:32.805 [main] DEBUG org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl - On call to EntityIdentifierReaderImpl#resolve, EntityKey was already known; should only happen on root returns with an optional identifier specified
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Resolving attributes for [inflearn.exjpa.jpaExample.Team#1]
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdBy` : value = null
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdBy`)  - enhanced for lazy-loading? - false
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdDate` : value = null
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdDate`)  - enhanced for lazy-loading? - false
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedBy` : value = null
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedBy`)  - enhanced for lazy-loading? - false
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedDate` : value = null
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedDate`)  - enhanced for lazy-loading? - false
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `members` : value = NOT NULL COLLECTION
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`members`)  - enhanced for lazy-loading? - false
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `name` : value = teamA
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`name`)  - enhanced for lazy-loading? - false
12:27:32.806 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done materializing entity [inflearn.exjpa.jpaExample.Team#1]
12:27:32.807 [main] DEBUG org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader - Done entity load : inflearn.exjpa.jpaExample.Team#1
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `username` : value = member1
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`username`)  - enhanced for lazy-loading? - false
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done materializing entity [inflearn.exjpa.jpaExample.Member#3]
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Resolving attributes for [inflearn.exjpa.jpaExample.Member#4]
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdBy` : value = null
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdBy`)  - enhanced for lazy-loading? - false
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdDate` : value = null
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdDate`)  - enhanced for lazy-loading? - false
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedBy` : value = null
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedBy`)  - enhanced for lazy-loading? - false
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedDate` : value = null
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedDate`)  - enhanced for lazy-loading? - false
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `memberProducts` : value = NOT NULL COLLECTION
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`memberProducts`)  - enhanced for lazy-loading? - false
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `team` : value = 2
12:27:32.807 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`team`)  - enhanced for lazy-loading? - false
12:27:32.807 [main] DEBUG org.hibernate.SQL - 
Hibernate: // teamB
    select
        team0_.TEAM_ID as team_id1_7_0_,
        team0_.createdBy as createdb2_7_0_,
        team0_.createdDate as createdd3_7_0_,
        team0_.lastModifiedBy as lastmodi4_7_0_,
        team0_.lastModifiedDate as lastmodi5_7_0_,
        team0_.name as name6_7_0_ 
    from
        Team team0_ 
    where
        team0_.TEAM_ID=?
12:27:32.808 [main] DEBUG org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl - On call to EntityIdentifierReaderImpl#resolve, EntityKey was already known; should only happen on root returns with an optional identifier specified
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Resolving attributes for [inflearn.exjpa.jpaExample.Team#2]
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdBy` : value = null
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdBy`)  - enhanced for lazy-loading? - false
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdDate` : value = null
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdDate`)  - enhanced for lazy-loading? - false
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedBy` : value = null
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedBy`)  - enhanced for lazy-loading? - false
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedDate` : value = null
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedDate`)  - enhanced for lazy-loading? - false
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `members` : value = NOT NULL COLLECTION
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`members`)  - enhanced for lazy-loading? - false
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `name` : value = teamB
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`name`)  - enhanced for lazy-loading? - false
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done materializing entity [inflearn.exjpa.jpaExample.Team#2]
12:27:32.809 [main] DEBUG org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader - Done entity load : inflearn.exjpa.jpaExample.Team#2
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `username` : value = member2
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`username`)  - enhanced for lazy-loading? - false
12:27:32.809 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done materializing entity [inflearn.exjpa.jpaExample.Member#4]
12:27:32.810 [main] DEBUG org.hibernate.engine.transaction.internal.TransactionImpl - committing
12:27:32.810 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Processing flush-time cascades
12:27:32.810 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Dirty checking collections
12:27:32.810 [main] DEBUG org.hibernate.engine.internal.Collections - Collection found: [inflearn.exjpa.jpaExample.Member.memberProducts#3], was: [inflearn.exjpa.jpaExample.Member.memberProducts#3] (uninitialized)
12:27:32.810 [main] DEBUG org.hibernate.engine.internal.Collections - Collection found: [inflearn.exjpa.jpaExample.Member.memberProducts#4], was: [inflearn.exjpa.jpaExample.Member.memberProducts#4] (uninitialized)
12:27:32.810 [main] DEBUG org.hibernate.engine.internal.Collections - Collection found: [inflearn.exjpa.jpaExample.Team.members#1], was: [inflearn.exjpa.jpaExample.Team.members#1] (uninitialized)
12:27:32.810 [main] DEBUG org.hibernate.engine.internal.Collections - Collection found: [inflearn.exjpa.jpaExample.Team.members#2], was: [inflearn.exjpa.jpaExample.Team.members#2] (uninitialized)
12:27:32.810 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Flushed: 0 insertions, 0 updates, 0 deletions to 4 objects
12:27:32.810 [main] DEBUG org.hibernate.event.internal.AbstractFlushingEventListener - Flushed: 0 (re)creations, 0 updates, 0 removals to 4 collections
12:27:32.810 [main] DEBUG org.hibernate.internal.util.EntityPrinter - Listing entities:
12:27:32.810 [main] DEBUG org.hibernate.internal.util.EntityPrinter - inflearn.exjpa.jpaExample.Team{createdDate=null, createdBy=null, lastModifiedDate=null, lastModifiedBy=null, members=<uninitialized>, name=teamB, id=2}
12:27:32.810 [main] DEBUG org.hibernate.internal.util.EntityPrinter - inflearn.exjpa.jpaExample.Member{createdDate=null, createdBy=null, lastModifiedDate=null, lastModifiedBy=null, memberProducts=<uninitialized>, id=4, team=inflearn.exjpa.jpaExample.Team#2, username=member2}
12:27:32.810 [main] DEBUG org.hibernate.internal.util.EntityPrinter - inflearn.exjpa.jpaExample.Member{createdDate=null, createdBy=null, lastModifiedDate=null, lastModifiedBy=null, memberProducts=<uninitialized>, id=3, team=inflearn.exjpa.jpaExample.Team#1, username=member1}
12:27:32.810 [main] DEBUG org.hibernate.internal.util.EntityPrinter - inflearn.exjpa.jpaExample.Team{createdDate=null, createdBy=null, lastModifiedDate=null, lastModifiedBy=null, members=<uninitialized>, name=teamA, id=1}
12:27:32.811 [main] DEBUG org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl - Initiating JDBC connection release from afterTransaction
12:27:32.812 [main] DEBUG org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl - Initiating JDBC connection release from afterTransaction
12:27:32.812 [main] DEBUG org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl - HHH000420: Closing un-released batch
12:27:32.812 [main] DEBUG org.hibernate.internal.SessionFactoryImpl - HHH000031: Closing
12:27:32.812 [main] DEBUG org.hibernate.type.spi.TypeConfiguration$Scope - Un-scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@54e12f4c] from SessionFactory [org.hibernate.internal.SessionFactoryImpl@3e134896]
12:27:32.812 [main] DEBUG org.hibernate.service.internal.AbstractServiceRegistryImpl - Implicitly destroying ServiceRegistry on de-registration of all child ServiceRegistries
12:27:32.812 [main] INFO org.hibernate.orm.connections.pooling - HHH10001008: Cleaning up connection pool [jdbc:h2:tcp://localhost/~/test]
12:27:32.814 [main] DEBUG org.hibernate.boot.registry.internal.BootstrapServiceRegistryImpl - Implicitly destroying Boot-strap registry on de-registration of all child ServiceRegistries

종료 코드 0(으)로 완료된 프로세스

 

즉, N + 1이란 게 뭐냐면,

1은 최초 쿼리

처음 쿼리를 하나 날렸는데, 그거 때문에 날아가는 추가 쿼리 N

 

그런데 이거를

LAZY로 다시 잡아주면

이것만 나오고 나머지 쿼리는 안 나온다.

 

팀은 프록시로 다 박혀있으니까.

물론 팀을 루프로 돌리면 쿼리는 계속 나가긴 할 거다.

 

이 문제를 해결하는 근본적인 방법은

1) 모든 연관관계 설정을 LAZY로 다 깔아놓는다.

* 2-1) 패치 조인 활용

2-2) 엔티티 그래프 어노테이션 활용

2-3) 배치 사이즈

이것들은 뒤에서 더 자세히 베을 것이다.

 

728x90

'Spring > JPA 공부' 카테고리의 다른 글

영속성 전이(CASCADE)  (0) 2023.08.25
지연 로딩 활용  (0) 2023.08.24
지연 로딩  (0) 2023.08.24
프록시  (0) 2023.08.24
실전 예제 - 4. 상속관계 매핑  (0) 2023.08.23
Comments