-
-
안녕하세요? 오늘은 JPA에서 중요한 핵심 기능인 즉시로딩과 지연로딩에 대해서 알아보도록 하겠습니다.
※ 지난 시간에서 다뤘던 프록시의 개념을 참고해주세요.
지연로딩 (LAZY)
: 불필요한 데이터의 정보 조회를 막기 위해 사용
ex) entityA 엔티티와 entityB 엔티티가 존재하고, 서로 단방향 N:1 매핑이 되어있다는 전제하에, entityB 의 데이터를 제외 한, entityA 의 데이터만 다루고 싶을때
EntityA 엔티티 생성)
@Entity
public class EntityA {
@Id @GeneratedValue
@Column(name = "ENTITYA_ID")
private Long id;
@Column(name = "ENTITYA_NAME")
private String name;
@ManyToOne(fetch = FetchType.LAZY) // ★★★
@JoinColumn(name = "ENTITYB_ID")
private EntityB entityB;
...
}
EntityB 엔티티 생성)
@Entity
public class EntityB {
@Id @GeneretedValue
@Column(name = "ENTITYB_ID")
privatae Long id;
@Column(name = "ENTITYB_NAME")
privaate String name;
...
}
샘플코드)
EntityManagerFactory emf = Persistence.createEntityManagerFactory("유닛명");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
EntityB entityB = new EntityB();
entityB.setName("entityB_1");
em.persist(entityB);
EntityA entityA = new EntityA();
entityA.setName("entityA_1");
em.persist(entityA);
em.flush();
em.close();
EntityA findEntityA = em.finid(EntityA.class, entityA.getId());
// 프록시 상태 반환
System.out.println("entityA : " + entityA.getEntityB().getClass());
// 해당 시점에 실제 DB 데이터를 조회 후, 반환
System.out.println("entityA : " + entityA.getEntityB().getName());
tx.commit();
+
해당 내용을 설명하자면, EntityA 엔티티를 조회 할 때, EntityB 의 엔티티 정보는, 지연로딩을 사용해서 프록시로 조회를 하게 된 상태로써, EntityB 의 속성을 사용할 때, DB에서 EntityB 의 정보를 조회하게 된다.
(LAZY 로딩 == 지연로딩)
즉시로딩 (EAGER)
: 조회를 할 때, 애초부터 Join을 걸어서, 한방에 모든 데이터를 가지고 오게 된다.
: 프록시가 아닌, 실제 엔티티가 반환
: 예상치 못한 SQL 이 반환
: JQPL에서 N+1 문제 발생
EntityA 엔티티 생성)
@Entity
public class EntityA {
@Id @GeneratedValue
@Column(name = "ENTITYA_ID")
private Long id;
@Column(name = "ENTITYA_NAME")
private String name;
@ManyToOne(fetch = FetchType.EAGER) // ★★★
@JoinColumn(name = "ENTITYB_ID")
private EntityB entityB;
...
}
EntityB 엔티티 생성)
@Entity
public class EntityB {
@Id @GeneretedValue
@Column(name = "ENTITYB_ID")
privatae Long id;
@Column(name = "ENTITYB_NAME")
privaate String name;
...
}
샘플코드)
EntityManagerFactory emf = Persistence.createEntityManagerFactory("유닛명");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
EntityB entityB = new EntityB();
entityB.setName("entityB_1");
em.persist(entityB);
EntityA entityA = new EntityA();
entityA.setName("entityA_1");
em.persist(entityA);
em.flush();
em.close();
EntityA findEntityA = em.finid(EntityA.class, entityA.getId());
// 해당 시점에 실제 DB 데이터를 조회 후, 반환
System.out.println("entityA : " + entityA.getEntityB().getClass());
// 영속성 컨텍스트의 entityB 정보 반환
System.out.println("entityA : " + entityA.getEntityB().getName());
tx.commit();
+
해당 내용을 설명하자면, EntityA 엔티티를 조회 할 때, EntityB 의 엔티티 정보는, 즉시로딩을 사용해서 조회를 하게 된 상태로써, 처음부터 EntityB 의 정보를 같이 Join해서 EntityA 정보를 가지고 오게 된다.
연관관계들의 기본 로딩 설정 값 ★★★
연관관계 | 기본 설정값 |
@ManyToOne | 즉시로딩 |
@OneToOne | 즉시로딩 |
@OneToMany | 지연로딩 |
@ManyToMany | 지연로딩 |
오늘은 JPA에서 중요한 핵심 기능인 즉시로딩과 지연로딩에 대해서 알아보았습니다.
그럼 오늘도 즐거운 하루 되시길 바라겠습니다.
'프로그래밍 > Back-end' 카테고리의 다른 글
JPA JPQL 경로 표현식 (0) | 2024.10.23 |
---|---|
JPA JPQL 타입 표현식과 기타식 그리고 조건식과 기본 함수 (0) | 2024.10.18 |
JPA 쿼리 JPQL 페이징 조인 서브쿼리 (0) | 2024.10.18 |
JPA QueryDSL 네이티브SQL JDBC MyBatis (0) | 2024.10.18 |
JPA 지연로딩 즉시로딩 프록시 proxy (0) | 2024.10.17 |
JPA 영속성 전이 CASCADE 고아 객체 (0) | 2024.10.15 |
JPA 영속성 영속상태와 준영속상태 (0) | 2024.10.15 |
JPA 영속성 Flush (0) | 2024.10.15 |