- 개념: 엔티티를 영구 저장하는 환경 (논리적인 개념)
- EntityManager를 통해서 영속성 컨텍스트에 접근 할 수 있다.
- 과거(J2Se)에는 엔티티 매니저와 영속성 컨텍스트가 1:1 매핑되었으나, 현재(Spring)는 N:1로 매칭된다.
- 엔티티의 생명주기
- 비영속(new/transient): 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
- 영속(managed): 영속성 컨텍스트에 관리되는 상태
- 준영속(detached): 영속성 컨텍스트에 저장되었다가 분리된 상태.
- 영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)된 상태
- 영속성 컨텍스트가 제공하는 기능을 사용 못함(dirty checking)
- 엔티티를 준영속 상태로 만드는 방법
- entityManager.detach(entity) ⇒ 특정 엔티티에 한하여 상태를 준영속으로 전환
- entityManager.clear() ⇒ 영속성 컨텍스트를 완전히 초기화
- entityManager.close() ⇒ 영속성 컨텍스트를 종료
- 삭제(removed): 삭제된 상태
- 영속성 컨텍스트의 이점
- 1차캐시
- 동일성(identity) 보장
⇒ 1차 캐시로 반복 가능한 읽기 등급의 트랜잭션 격리 수준을 DB가 아닌 애플리케이션 차원에서 제공
- 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)
- persist하는 순간 쓰기 지연 SQL 저장소에 해당 쿼리를 생성
- 트랜잭션이 커밋되는 순간 데이터베이스에 해당 쿼리를 보낸다.
- 변경감지(Dirty Checking)
- 트랜잭션이 끝나는 시점에 영속 컨텍스트는 1차 캐시 내에 엔티티와 스냅샷을 비교하여 변경 사항을 감지한다.
- 변경 사항을 기반으로 쓰기 지연 SQL 저장소에 쿼리를 저장하고 DB에 전달하게된다.
- 지연 로딩(Lazy Loading
- 플러시 (Flush)
- 개념: 영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 작업.
- 플러시 할 시 진행되는 작업
- 변경감지 ⇒ 1차 캐시 내 엔티티 ↔ 스냅샷 비교
- 수정된 엔티티에 대한 쿼리 → 쓰기 징ㄴ SQL 저장소에 등록
- 쓰기 지연 SQL 저장소의 쿼리를 DB에 전송
- 영속성 컨텍스트를 플러시하는 방법
- 직접 호출
- entityManager.flush()
- 자동 호출
- 트랜잭션 커밋
- JPQL 쿼리 실
- 특징
- 플러시는 영속성 컨텍스트를 비우지 않음 ⇒ 단순히 변경 내용을 DB에 동기화 하는 것.
- 플러시에 있어서 트랜잭션이라는 작업 단위가 중요 ⇒ 커밋 직전에만 동기화 하면 됨.