자바 ORM 표준 JPA 프로그래밍 기본편 - 3. 영속성 관리 - 내부 동작 방식

Updated:

김영한님의 인프런 강의 - 자바 ORM 표준 JPA 프로그래밍 - 기본편
위 강의를 정리한 내용입니다.

I. 영속성 컨텍스트

  • JPA에서 가장 중요한 2가지
    1. 객체와 관계형 데이터베이스 매핑하기
    2. 영속성 컨텍스트

개요

  • 엔티티를 영구 저장하는 환경
  • EntityManager.persist(entity);
  • 현재 환경에서는 EM : 영속성 컨텍스트 = 1 : 1
  • 스프링에서는 EM : 영속성 컨텍스트 = N : 1

엔티티의 생명주기

비영속

  • 객체를 생성만 한 상태.
  • 아직 JPA와는 전혀 관계가 없다.

영속

  • 생성한 객체를 EntityManagerpersist한 상태.
  • EntityManager내부의 영속성컨텍스트에 의해 관리된다.
  • 영속되어도 아직 쿼리가 날라가지는 않는다. 즉 디비에 저장되지 않는다.

준영속, 삭제

  • 영속상태의 객체를 다시 제외시킨다.

왜 영속성 컨텍스트가 필요한가?

1차 캐시

  • em.find실시할 때 데이터베이스보다 먼저 1차캐시를 조회한다.
  • 만약 1차캐시에 없다면 DB를 조회하고 1차캐시에 저장한 후 1차캐시에서 다시 반환한다.
  • 수많은 EntityManager가 생성되고 사라지기 때문에 1차캐시로 사실상 큰 이점을 가지진 않는다.

영속 엔티티의 동일성 보장

  • 마치 컬렉션이서 꺼내는 것 처럼 같은 Entity를 꺼내면 둘의 동일성을 보장해준다. (==비교시 true를 반환한다)

엔티티 등록 - 트랜잭션을 지원하는 쓰기 지연

  • 트랜잭션을 시작하고나서 커밋하기 전까지 모든 INSERT문을 보내지 않고 쌓아둔다.

엔티티 수정 - 변경 감지

  • DB에서 꺼내온 Entity를 수정하면 다시 persist하지 않아도 알아서 변경을 감지하고 DB에 적용한다.
  • 1차캐시 안에는 @IdEntity 외에도 최초로 1차캐시에 들어온 상태를 저장하는 스냅샷이 있다.
  • 만약 스냅샷과 Entity가 다르다면 쓰기 지연 SQL 저장소에 UPDATE쿼리를 올려놓는다.

II. 플러시

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

플러시 발생

  • 변경 감지
  • 수정된 엔티티를 쓰기 지연 SQL 저장소에 등록
  • 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송
  • 1차캐시는 지워지지 않고 유지된다.

플러시하는 방법

  • em.flush() - 직접 호출
  • 트랜잭션 커밋 - 플러시 자동 호출
  • JPQL 쿼리 실행 - 플러시 자동 호출
    • JPQL은 즉시 날라가는데, 필요한 데이터가 쓰기 지연 SQL 저장소에 있으면 조회가 불가능하므로 JPQL쿼리 실행시 flush된다.
    • 플러시 옵션
      • em.setFlushMode(FlushModeType.AUTO) : 커밋이나 쿼리를 실행할 때 플러시(기본값)
      • em.setFlushMode(FlushModeType.COMMIT) : 커밋할 때만 플러시

III. 준영속 상태

  • 영속 -> 준영속
  • 영속 상태였던 엔티티가 영속성 컨텍스트에서 분리
  • 영속성 컨텍스트가 제공하는 기능을 사용 못함

준영속 상태로 만드는 방법

  • em.detach(entity) : 특정 엔티티 지우기
  • em.clear() : 영속성 컨텍스트 통째로 지우기
  • em.close() : 영속성 컨텍스트를 종료

Leave a comment