영속성 컨텍스트
JPA 에서 가장 중요한 2가지
- 객체와 관계형 데이터베이스 매핑하기 ( Object Relational Mapping ) -> 정적인 매핑과정
- 영속성 컨텍스트 - 실제 JPA 가 어떻게 내부적으로 동작하는지에 대한 이해 -> 동작하는 메커니즘
엔티티 매니저 팩토리와 엔티티 매니저

웹 어플리케이션을 만든다고 했을 때, entityManagerFactory 는 고객의 요청에 의해 entityManager 를 생성한다. entityManager는 내부적으로 DB connection 을 사용하여 DB 와 통신한다.
영속성 컨텍스트란?
JPA 를 이해하는데 가장 중요한 용어로, 엔티티를 영구 저장하는 환경 이라는 뜻이다.
( EntityManager.persist(entity); ) 에서 persist 메소드는 DB 에 저장하는 것이 아닌 "영속성 컨텍스트"에 저장하는 메소드이다.
영속성 컨텍스트는 논리적인 개념이고 눈에 보이지 않는다.
엔티티 매니저를 통해서 영속성 컨텍스트에 접근한다.
엔티티의 생명주기

- 비영속(new/transient) : 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
- 영속(managed) : 영속성 컨텍스트에 관리되는 상태
- 준영속(detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태
- 삭제(removed) : 삭제된 상태
트랜잭션을 커밋하는 시점에 영속성 컨텍스트에 담겨있는 객체들이 DB 에 반영된다.
영속성 컨테스트의 이점
애플리케이션과 DB 사이에 중간 계층으로 동작하기 때문에 버퍼링, 캐싱을 할 수 있다.
1차 캐시
- 객체를 persist 메소드로 저장하고, find 메소드로 조회할 때 DB 부터 찾는 것이 아닌 영속성 컨텍스트( 1차 캐시 )에서 먼저 찾아 값이 존재한다면 리턴해준다.
- 1차 캐시에 없는 경우 JPA 가 DB 에서 조회를 수행한 뒤, 1차 캐시에 저장한 후 리턴해준다.
- 영속성 컨텍스트는 트랜잭션 단위로 생성하고, 트랜잭션이 종료될 때 영속성 컨텍스트 또한 종료한다. 고객의 요청이 들어와서 비지니스가 끝나면 영속성 컨텍스트를 지운다는 것이다. 따라서 애플리케이션 전체에서 공유하는 캐시가 아니다.
- 따라서 DB 트랜잭션 안에서 잠깐 발생하는 캐시이기 때문에 성능적으로 얻을 수 있는 이점이 많지는 않다.
동일성 보장 ( identity )
트랜잭션을 지원하는 쓰기 지연 ( transactional write-behind )

- 트랜잭션을 커밋하는 순간 SQL 을 보낸다.
<property name="hibernate.jdbc.batch_size" value="10"/>를 이용하여 쿼리를 모아서 한 번에 DB 에 적용할 수 있는 버퍼링 이점을 얻을 수 있다.
변경 감지 ( dirty checking )

지연 로딩 ( lazy loading )
플러시란?
- 영속성 컨텍스트의 변경내용을 DB 에 반영하는 것. ( 영속성 컨텍스트와 DB 의 내용을 맞추는 것 )
- 플러시가 발생하면 변경을 감지하고 수정된 엔티티 쓰기 지연 SQL 저장소에 등록하고 쓰기 지연 SQL 저장소의 쿼리를 DB 에 전송한다.
- 영속성 컨텍스트를 비우는 것이 아니다!
- 영속성 컨텍스트의
변경내용을 DB 에 동기화하는 것이다. - 트랜잭션이라는 작업 단위가 중요하므로 커밋 직전에만 동기화를 하면 된다.
영속성 컨텍스트를 플러시하는 방법
- em.flush() - 직접 호출
- 트랜잭션 커밋 - 플러시 자동 호출
- JPQL 쿼리 실행 - 플러시 자동 호출
준영속 상태란?
- 영속 상태의 엔티티가 영속성 컨텍스트에서 분리 ( detached ) 된 상태, 영속성 컨텍스트가 제공하는 기능을 사용하지 못한다.
- 준영속 상태로 만드는 방법
- em.detach(entity) : 특정 엔티티만 준영속 상태로 전환
- em.clear() : 영속성 컨텍스트를 완전히 초기화
- em.close() : 영속성 컨텍스트 종료
REFERENCES
'Spring Data' 카테고리의 다른 글
| JPA Open Session In View (0) | 2021.11.03 |
|---|---|
| JPA 변경감지와 병합 (0) | 2021.11.03 |
| JPA Proxy (0) | 2021.11.03 |
| 연관관계 주인과 mappedBy (0) | 2021.11.03 |
| @OneToOne, @ManyToMany (0) | 2021.11.03 |