코드 그라데이션
지연 로딩 본문
반복된 고민
예시
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());
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace(); // 하나 찍어봄
} finally {
em.close();
}
emf.close();
}
}
멤버를 조회할 때는 멤버만 가져오고, 팀은 프록시로 가져오는 것을 확인할 수 있음.
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_
from
Member member0_
where
member0_.MEMBER_ID=?
11:19:03.102 [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:19:03.106 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Resolving attributes for [inflearn.exjpa.jpaExample.Member#2]
11:19:03.106 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdBy` : value = null
11:19:03.106 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdBy`) - enhanced for lazy-loading? - false
11:19:03.106 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdDate` : value = null
11:19:03.106 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdDate`) - enhanced for lazy-loading? - false
11:19:03.106 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedBy` : value = null
11:19:03.106 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedBy`) - enhanced for lazy-loading? - false
11:19:03.106 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedDate` : value = null
11:19:03.106 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedDate`) - enhanced for lazy-loading? - false
11:19:03.106 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `memberProducts` : value = NOT NULL COLLECTION
11:19:03.106 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`memberProducts`) - enhanced for lazy-loading? - false
11:19:03.107 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `team` : value = 1
11:19:03.107 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`team`) - enhanced for lazy-loading? - false
11:19:03.110 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `username` : value = member1
11:19:03.110 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`username`) - enhanced for lazy-loading? - false
11:19:03.110 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done materializing entity [inflearn.exjpa.jpaExample.Member#2]
11:19:03.111 [main] DEBUG org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader - Done entity load : inflearn.exjpa.jpaExample.Member#2
m = class inflearn.exjpa.jpaExample.Team$HibernateProxy$3y6UBNCz
쿼리는
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(); // 쿼리 나가는 시점
System.out.println("이후===================");
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace(); // 하나 찍어봄
} finally {
em.close();
}
emf.close();
}
}
로그는
// 팀을 터치하는 시점에 멤버를 먼저 조회
11:21:37.063 [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_
from
Member member0_
where
member0_.MEMBER_ID=?
m = class inflearn.exjpa.jpaExample.Team$HibernateProxy$4I9ogux7 // 클래스 타입(프록시) 찍고
이전===================
11:21:37.077 [main] DEBUG org.hibernate.internal.SessionImpl - Initializing proxy: [inflearn.exjpa.jpaExample.Team#1]
11:21:37.077 [main] DEBUG org.hibernate.SQL -
// 실제 팀을 사용하는 시점에 프록시 객체가 초기화되면서 DB에서 이 값을 가지고 온다.
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=?
11:21:37.078 [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:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Resolving attributes for [inflearn.exjpa.jpaExample.Team#1]
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdBy` : value = null
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdBy`) - enhanced for lazy-loading? - false
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `createdDate` : value = null
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`createdDate`) - enhanced for lazy-loading? - false
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedBy` : value = null
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedBy`) - enhanced for lazy-loading? - false
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `lastModifiedDate` : value = null
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`lastModifiedDate`) - enhanced for lazy-loading? - false
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `members` : value = NOT NULL COLLECTION
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`members`) - enhanced for lazy-loading? - false
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Processing attribute `name` : value = teamA
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Attribute (`name`) - enhanced for lazy-loading? - false
11:21:37.079 [main] DEBUG org.hibernate.engine.internal.TwoPhaseLoad - Done materializing entity [inflearn.exjpa.jpaExample.Team#1]
11:21:37.079 [main] DEBUG org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader - Done entity load : inflearn.exjpa.jpaExample.Team#1
이후===================
지연 로딩으로 세팅하면
연관된 걸 프록시로 가지고 온다.
지연 로딩
지연 로딩 LAZY를 사용하여 프록시로 조회
728x90
'Spring > JPA 공부' 카테고리의 다른 글
지연 로딩 활용 (0) | 2023.08.24 |
---|---|
즉시 로딩 (0) | 2023.08.24 |
프록시 (0) | 2023.08.24 |
실전 예제 - 4. 상속관계 매핑 (0) | 2023.08.23 |
@MappedSuperclass (0) | 2023.08.23 |
Comments