코드 그라데이션
즉시 로딩 본문
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