[JPA] 영속성 컨텍스트
JPA의 핵심 개념인 영속성 컨텍스트에 대해서 알아보자
[JPA] 영속성 컨텍스트
※ 코드는 강의에서 사용된 것과 다릅니다.
<a href = https://github.com/jaewon-ju/Learning_Spring>jaewon-ju Github Address</a>
✏️ 영속성 컨텍스트
영속성 컨텍스트 (Persistence Context)
: 엔티티를 영구 저장하는 환경
- 애플리케이션 ⇔ DB 사이에서 객체를 보관하는 가상의 환경이다.
EntityManager를 통해서 영속성 컨텍스트에 접근할 수 있다.
1
2
EntityManager.persist(member);
// member 엔티티를 영속성 컨텍스트에 저장하는 코드
✏️ 주요 기능
영속성 컨텍스트의 주요 기능은 다음과 같다.
- 엔티티의 생명 주기 관리
- 1차 캐시
- 동일성 보장
- 변경 감지
- 지연 로딩
- Transcational Write Behind
1. 엔티티의 생명 주기 관리
영속성 컨텍스트는 엔티티의 생명주기 상태(비영속, 영속, 준영속, 삭제)를 관리한다.
| 상태 | 설명 |
|---|---|
| 비영속(New) | 엔티티가 생성되었지만, 아직 영속성 컨텍스트에 저장되지 않음 |
| 영속(Managed) | 엔티티가 영속성 컨텍스트에 저장됨 |
| 준영속(Detached) | 엔티티가 영속성 컨텍스트에 저장되었다가 분리됨 |
| 삭제(Removed) | 삭제됨 |
-
엔티티를 영속 상태로 만들기 위해서는, Transaction을 시작한 뒤에
em.persist()메소드를 실행하면 된다. -
flush()메소드를 실행하면, 영속성 컨텍스트의 변경내용이 데이터베이스에 반영된다.
2. 1차 캐시
영속성 컨텍스트는 엔티티의 식별자(PK)를 키로 하여 1차 캐시를 유지/관리 한다.
1차 캐시
: 영속 상태의 엔티티를 저장하는 영속성 컨텍스트 내부의 캐시
em.persist(member)를 실행하면member엔티티가 1차 캐시에 저장된다.- 1차 캐시에 저장되어 있는 엔티티를 조회할 때는 DB에 접근할 필요가 없다!
- DB에서 엔티티를 조회할 때도 1차 캐시에 해당 엔티티가 저장된다.
3. 동일성 보장
영속성 컨텍스트는 엔티티의 동일성을 보장한다.
1
2
3
4
Order a = em.find(Order.class, "order1");
Order b = em.find(Order.class, "order1");
System.out.println(a == b); // true 반환
4. 변경 감지 (Dirty Checking)
영속성 컨텍스트는 엔티티의 초기 상태(영속될 때의 상태)를 스냅샷으로 보관하고, 트랜잭션을 커밋할 때 엔티티의 현재 상태와 비교하여 변경된 점이 있으면 데이터베이스에 자동으로 반영한다.
1
2
3
4
5
6
7
8
9
Order orderA = em.find(Order.class, "orderA");
// 1차 캐시에 엔티티 저장 - 스냅샷으로 보관
orderA.setTitle("수박");
orderA.setPrice("10000");
// entity가 수정되었음
// 영속성 컨텍스트가 자동으로 변경을 감지하여 UPDATE 쿼리를 SQL 저장소에 저장한다.
transaction.commit();
5. 지연 로딩
지연 로딩
: 엔티티와 연관된 다른 엔티티를 즉시 로드하지 않고, 실제로 사용될 때 로드하는 방법
이후에 Proxy와 함께 자세히 설명하겠다.
6. Transactional Write-Behind
Transactional Write-Behind
: 엔티티의 변경사항을 즉시 DB에 반영하지 않고, 트랜잭션을 커밋할 때 일괄적으로 반영하는 기술
- 애플리케이션에서 엔티티의 상태 변경이 발생하면, 변경된 사항들은 영속성 컨텍스트 내에서 추적된다.
- 해당 변경사항들은 DB에 즉시 반영되지 않고, 메모리 내에 적재된다.
- 트랜잭션이 커밋되는 시점에 모든 누적된 변경사항이 데이터베이스로 일괄적으로 전송
✏️ flush
플러시란, 영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 작업이다. 영속성 컨텍스트를 플러시하는 방법은 3가지가 존재한다.
em.flush- 직접 호출transcation.commit()- 자동 호출- JPQL 쿼리 실행 - 자동 호출
⚠️ 플러시는 영속성 컨텍스트를 비우는 것이 아니다!
REFERENCE
This post is licensed under
CC BY 4.0
by the author.