영속성 콘텍스트
엔티티를 영구 저장하는 환경이라는 의미
애플리케이션과 데이터베이스사이에서
객체를 보관하는 가상의 데이터베이스 같은 역할을 한다.
엔티티 매니저를 통해 엔티티를 저장하거나 조회하면 매니저는
영속성 콘텍스트에 엔티티를 보관하고 관리한다.
엔티티의 생명주기
- 비영속(new/transit) : 영속성 콘텍스트와 전혀 관계가 없는 상태
Product product = new Product();
product.setId("product1");
product.setName("책");
객체를 생성하였지만 저장은 되지 않음
- 영속(managed) : 영속성 콘텍스트에 저장된 상태
Product product = new Product();
product.setId("product1");
product.setName("책");
EntityManager em = em.createEntityManager();
em.getTransaction().begin();
em.persist(product);
- 준영속(detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태
// 엔티티를 영속성 컨텍스트에서 분리해 준영속 상태로 만든다.
em.detach(product);
// 영속성 컨텍스트를 비워도 관리되던 엔티티는 준영속 상태가 된다.
em.clear();
// 영속성 컨텍스트를 종료해도 관리되던 엔티티는 준영속 상태가 된다.
em.close();
준영속 상태의 특징
- 1차 캐시, 쓰기 지연, 변경 감지, 지연 로딩을 포함한 영속성 콘텍스트가 제공하는 어떠한 기능도 동작하지 않는다.
- 식별자 값을 가지고 있다.
- 삭제(removed) : 삭제된 상태
em.remove(product);
영속성 콘텍스트의 특징
영속성 컨텍스트의 식별자 값
영속성 콘텍스트는 엔티티를 식별자 값으로 구분한다. 따라서 영속 상태는 식별자 값이 반드시 있어야 한다.
영속성 콘텍스트와 데이터베이스 저장
JPA는 보통 트랜잭션을 커밋하는 순간 영속성 콘텍스트에 새로 저장된 엔티티를 데이터베이스에 반영하는데
이를 "flush" 라고 한다.
영속성 콘텍스트의 이점
- 1차 캐시
1차 캐시는 영속성 콘텍스트 내부에 존재한다. 영속 상태의 엔티티를 이곳에 저장한다.
1차 캐시의 키는 식별자 값(데이터베이스의 기본 키)이고 값은 엔티티인스턴스이다.
➜ 식별자 값 : @Id
➜ 값 : value
엔티티 매니저가 조회를 할 때 먼저 영속성 콘텍스트에 있는 1차 캐시에서 해당 엔티티를 찾고 엔티티가 존재할 경우 DB에 접근하지 않고 반환한다.
엔티티가 존재하지 않을 경우 엔티티 매니저가 em.flush() 할 때에 데이터베이스에 접근해서 엔티티를 꺼내오고 해당 해당 엔티티를 꺼내오고 해당 엔티티를 1차캐시에 저장한다. - 동일성 보장(Identity)
영속성 콘텍스트에서 꺼내온 객체는 동일성이 보장된다.
같은 엔티티를 두 번 조회할 경우 두 개의 엔티티는 동일한 엔티티이다.
1차 캐시로 반복 가능한 읽기(REPEATABLE READ) 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공한다. - 트랜잭션을 지원하는 쓰기 지연
트랜잭션 내부에서 persist()가 일어날 때, 엔티티들을 1차 캐시에 저장하고, 쓰기 지연 SQL저장소라는 곳에 INSERT 쿼리들을 생성해서 쌓아 놓는다.
DB에 바로 넣지 않고 기다린다.
commit() 또는 flush()를 할 때 쓰기 지연 SQL 저장소에 저장되어 있는 SQL들을 DB에 보낸다. - 변경 감지
JPA에서는 엔티티를 업데이트할 때 update(), persist()와 같은 메서드로 영속성 콘텍스트에 알려주지 않아도 된다. 이것이 가능한 이유는 변경감지(Dirty Checking) 덕분이다.
엔티티 매니저가 엔티티를 1차 캐시에 저장할 때 스냅샷도 같이 저장한다. 트랜잭션이 커밋하는 시점에서 엔티티와 스냅숏을 비교해 변경사항이 있으면 Update SQL을 알아서 생성해서 쓰기 지연 저장소에 SQL을 저장한다.
➜ 값만 바뀌었는데 업데이트 쿼리가 발생하는 이유는 JPA가 엔티티 관리를 하고 트랙잭션이 커밋하는 시점에서 변경된 사항을 체크를하고 변경이 되었으면 업데이트 쿼리를 만들어서 요청하고 트랙잭션이 커밋이 됨 - 지연 로딩
프락시 객체를 로딩해두고 실제 사용할 때만 영속성 컨텍스트를 통해 데이터를 불러오는 방법.
➜ detached 상태이면 - 프록시 객체만 있는데 원본과의 연결이 없으므로 지연로딩
cascade
JPA에서 엔티티 선언 시 cascade를 설정하면, 부모가 자식의 영속성시점을 조절할 수 있다.
부모가 1차 캐시에 들어갈 때 같이 들어가고, 나올 때 같이 나오는 것 등
'자바 탐구' 카테고리의 다른 글
스프링) 스프링 컨테이너(Spring Container) (0) | 2023.07.24 |
---|---|
스프링) 의존성 주입(Dependency Injection) 방식 (0) | 2023.07.22 |
스프링) SpringSecurity - 11) Oauth2.0 네이버 로그인 완료 (0) | 2023.05.26 |
스프링) SpringSecurity - 10) Oauth2.0 페이스북 로그인 완료 (1) | 2023.05.26 |
스프링) SpringSecurity - 9) Oauth2.0 구글 로그인 및 자동 회원 가입 진행 완료 (0) | 2023.05.26 |