영속성 컨텍스트(Persistence Context)

jieunee·2021년 5월 20일
0
post-thumbnail
post-custom-banner

🔎 영속성 컨텍스트란?

엔티티를 영구 저장하는 환경을 뜻한다. 엔티티 매니저(Entity Manager)를 통해서 접근 가능하다.

🔹 활용 예시

em.persist(member); 

-> persist() 메소드를 통해 em(Entity Manager)을 사용해서 회원 엔티티를 영속성 컨텍스트에 저장함.

엔티티의 생명주기

엔티티의 생명주기에는 총 4가지 상태가 있다.

엔티티_생명주기

<엔티티 생명주기를 나타낸 그림>


1. 비영속(new/transient)

  • 영속성 컨텍스트와 전혀 관련이 없는 상태, 순수한 객체 상태

🔹 예시

Member meber = new Member();
member.setId("member1");
member.setUsername("회원1");

2. 영속(managed)

  • 영속성 컨텍스트에 저장된 상태
  • 영속성 컨텍스트에 의해 관리되는 상태
  • em.find() 혹은 JPQL로 조회한 엔티티도 영속 상태라고 본다.

🔹 예시

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

em.persist(member); // 영속 상태

3. 준영속(detached)

  • 영속성 컨텍스트에 저장되었다 분리된 상태
  • em.close() 혹은 em.clear()를 호출해서도 준영속 상태로 만들 수 있다.

🔹 예시

em.detach(member);

4. 삭제(removed)

  • 삭제된 상태

🔹 예시

em.remove(member);

영속성 컨텍스트의 특징

영속성 컨텍스트는 엔티티를 식별자 값(@Id로 테이블의 기본 키와 매핑한 값)으로 구분한다. 즉, 영속 상태는 식별자 값이 반드시 있어야 한다.


영속성 컨텍스트의 장점

1. 1차 캐시

  • 1차 캐시란 ?
    : 영속성 컨텍스트의 내부 캐시, 영속 상태의 엔티티는 모두 이곳에 저장된다.
  • 1차 캐시의 키는 식별자 값. 즉, 영속성 컨텍스트에 데이터 저장 및 조회 기준은 데이터베이스 기본 키 값이다.
  • em.find()를 호출했는데 엔티티가 1차 캐시에 없으면 엔티티 매니저는 데이터베이스를 조회한 후 엔티티를 생성한다.

🔹 예시 - 1차 캐시에 저장 및 조회

Member member = new Member();
member.setId("member1");
member.setUsername("회원1");

em.persist(member); //1차 캐시에 저장

Member member = em.find(Member.class, "member1"); //1차 캐시에서 조회, 기본 키 값인 id로 조회


2. 동일성(identity) 보장

  • em.find(Member.class, "member1")를 반복해서 호출해도 영속성 컨텍스트는 1차 캐시에 있는 같은 엔티티 인스턴스를 반환한다.
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");

System.out.println(a==b); //true 반환

3. 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)

transction.begin(); //트랜잭션 시작

em.persist(member1); 
em.persist(member2); //persist 할 때는 쓰기 지연 저장소에 차곡차곡 쌓아둠. 
  		     //즉, INSERT SQL을 데이터베이스에 보내지 않는다.

transaction.commit(); // 트랜잭션 커밋 = 버퍼링 같은 기능
  		      // 커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.

4. 변경 감지(Dirty Checking)

  • 엔티티의 변경사항을 데이터베이스에 자동으로 반영하는 기능이 있다.

5. 지연 로딩(Lazy Loading)

플러시(flush)

영속성 컨텍스트의 변경 내용을 데이터베이스에 반영하는 것

플러시가 발생했을 경우
1. 변경 감지 동작
2. 수정된 엔티티는 수정 쿼리를 만들어 쓰기 지연 SQL 저장소에 등록
3. 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송한다.(등록, 수정, 삭제 쿼리)

영속성 컨텍스트를 플러시 하는 방법

  • em.flush - 직접 호출(바로 변경사항이 반영된다.)
  • 트랜잭션 커밋 - 플러시 자동 호출
  • JPQL 쿼리 실행 - 플러시 자동 호출

플러시에 대해서 중요한 점

  • 영속성 컨텍스트를 비우는 것이 아닌, 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화하는 것이다.
  • 트랜잭션이라는 작업 단위가 중요하다.
    -> 커밋 직전에만 동기화 하면 된다.

준영속 상태

영속성 컨텍스트가 관리하는 영속 상태의 엔티티가 영속성 컨텍스트에서 분리된 상태, 이 때 엔티티는 영속성 컨텍스트가 제공하는 기능을 사용할 수 없다.

또한, 데이터베이스에 반영되지 않는다.


준영속 상태로 만드는 방법

  • em.detach(entity) : 특정 엔티티만 준영속 상태로 전환
  • em.clear() : 영속성 컨텍스트를 완전히 초기화
    1차 캐시를 다 지워버리는 것
  • em.close() : 영속성 컨텍스트를 종료


준영속 상태의 특징

  • 거의 비영속 상태에 가깝다.
  • 이미 한 번 영속 상태였기에 식별자 값을 갖고 있다.
  • 지연 로딩을 할 수 없다.


병합 - merge()

  • 준영속 상태의 엔티티를 다시 영속 상태로 변경하는 것

출처 : 인프런 김영한 - 자바 ORM 표준 JPA 프로그래밍(기본편)

profile
Back-End Developer 🌱
post-custom-banner

0개의 댓글