영속성 컨텍스트 (Persistence Context)
: 엔티티를 영구 저장하는 환경
EntityManager
를 통해서 영속성 컨텍스트에 접근할 수 있다.EntityManager.persist(member);
// member 엔티티를 영속성 컨텍스트에 저장하는 코드
영속성 컨텍스트의 주요 기능은 다음과 같다.
영속성 컨텍스트는 엔티티의 생명주기 상태(비영속, 영속, 준영속, 삭제)를 관리한다.
상태 | 설명 |
---|---|
비영속(New) | 엔티티가 생성되었지만, 아직 영속성 컨텍스트에 저장되지 않음 |
영속(Managed) | 엔티티가 영속성 컨텍스트에 저장됨 |
준영속(Detached) | 엔티티가 영속성 컨텍스트에 저장되었다가 분리됨 |
삭제(Removed) | 삭제됨 |
엔티티를 영속 상태로 만들기 위해서는, Transaction을 시작한 뒤에 em.persist()
메소드를 실행하면 된다.
flush()
메소드를 실행하면, 영속성 컨텍스트의 변경내용이 데이터베이스에 반영된다.
영속성 컨텍스트는 엔티티의 식별자(PK)를 키로 하여 1차 캐시를 유지/관리 한다.
1차 캐시
: 영속 상태의 엔티티를 저장하는 영속성 컨텍스트 내부의 캐시
em.persist(member)
를 실행하면 member
엔티티가 1차 캐시에 저장된다.영속성 컨텍스트는 엔티티의 동일성을 보장한다.
Order a = em.find(Order.class, "order1");
Order b = em.find(Order.class, "order1");
System.out.println(a == b); // true 반환
영속성 컨텍스트는 엔티티의 초기 상태(영속될 때의 상태)를 스냅샷으로 보관하고, 트랜잭션을 커밋할 때 엔티티의 현재 상태와 비교하여 변경된 점이 있으면 데이터베이스에 자동으로 반영한다.
Order orderA = em.find(Order.class, "orderA");
// 1차 캐시에 엔티티 저장 - 스냅샷으로 보관
orderA.setTitle("수박");
orderA.setPrice("10000");
// entity가 수정되었음
// 영속성 컨텍스트가 자동으로 변경을 감지하여 UPDATE 쿼리를 SQL 저장소에 저장한다.
transaction.commit();
지연 로딩
: 엔티티와 연관된 다른 엔티티를 즉시 로드하지 않고, 실제로 사용될 때 로드하는 방법
이후에 Proxy와 함께 자세히 설명하겠다.
Transactional Write-Behind
: 엔티티의 변경사항을 즉시 DB에 반영하지 않고, 트랜잭션을 커밋할 때 일괄적으로 반영하는 기술
플러시란, 영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 작업이다.
영속성 컨텍스트를 플러시하는 방법은 3가지가 존재한다.
em.flush
- 직접 호출transcation.commit()
- 자동 호출⚠️ 플러시는 영속성 컨텍스트를 비우는 것이 아니다!