영속성 관리 - JPA 내부 구조

.·2021년 9월 16일
0

JPA

목록 보기
2/2
post-thumbnail

영속성 컨텍스트

JPA에서 가장 중요한 2가지

  • 객체와 관계형 데이터베이스 매핑하기
  • 영속성 컨텍스트

영속성 컨텍스트란

  • 엔티티를 영구 저장하는 환경
  • 엔티티를 DB에 저장하는 것이 아니라, 영속성 컨텍스트에 저장
  • 영속성 컨텍스트는 논리적인 개념으로, 눈에 보이지 않는다.
  • 엔티티 매니저를 통해 영속성 컨텍스트에 접근
  • 엔티티 매니저는 내부적으로 DB 커넥션을 사용해 DB에 접근

엔티티의 생명주기

비영속

  • 영속성 컨텍스트와 전혀 관계가 없는 새로운상태
Member memeber = new Member();
member.setId(1L);
member.setUserName("건희");

영속

  • 영속성 컨텍스트에 관리되는 상태
// 객체를 생성한 상태 (비영속)
Member memeber = new Member();
member.setId(1L);
member.setUserName("건희");

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

// 객체를 저장한 상태(영속)
em.persist(member);

준영속, 삭제

  • 준영속 : 영속성 컨텍스트에 저장되었다가 분리된 상태
  • 삭제 : 삭제된 상태
// 영속 상태
em.persist(member);
em.persist(member2);
// 준영속 상태
em.detach(member);
// 삭제
em.remove(member2)

엔티티의 생명 주기

영속성 컨텍스트의 이점

  • 1차 캐시
  • 동일성 보장
  • 트랜잭션을 지원하는 쓰기 지연
  • 변경 감지

1차 캐시

  • id가 1인 member를 em.persist(member); 하게 되면 member가 영속성 컨택스트의 1차 캐시에 저장된다.
  • 1차 캐시는 key-value 구조로 되어있으며, key는 @Id("1"), value는 Entity(member) 값이 들어간다.
  • em.find(Member.class, 1L);을 실행하면 바로 DB를 조회하는 것이 아니라 영속성 컨텍스트의 1차 캐시를 먼저 조회한다
  • em.find(Member.class, 2L);를 조회한다면, 영속성 컨텍스트에 없으므로 DB에서 조회한다.
    그 후 그 정보를 1차 캐시에 저장한 후 id가 2인 member를 반환한다.
  • 사실 1차 캐시는 트랜잭션 단위로 만들어지므로,
    고객의 요청이 하나 들어온 후 종료되면 영속성 컨택스트도 지운다.
  • 따라서 비즈니스 로직이 매우 복잡한 경우가 아니라면 큰 성능 이점을 얻을 수는 없다.

동일성 보장

쓰기지연



변경감지

  • 트랜잭션을 커밋하면 flush()가 호출된다.
  • 그 후 1차 캐시 안에 있는 엔티티와 스냅샷을 비교한다.
  • 다르면 UPDATE 쿼리를 생성하여 쓰기 지연 SQL 저장소에 저장한다.
  • 쓰기 지연 SQL 저장소에 있던 SQL들이 flush 되면서 DB에 쿼리를 보낸 후 commit 된다.

스냅샷이란?
영속성 컨택스트의 1차 캐시에 들어온 최초 상태

플러시

플러시

  • 영속성 컨텍스트의 변경내용을 데이터베이스에 반영
  • 플러시가 발생하면 다음과 같은 상황이 일어난다
  • 변경감지
  • 수정된 엔티티 쓰기 지연 SQL 저장소에 등록
  • 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송

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

  • em.flush() - 직접 호출
  • 트랜잭션 커밋 - 플러시 자동 호출
  • JPQL 쿼리 실행 - 플러시 자동 호출

플러시의 특징

  • 영속성 컨텍스트를 비우지 않음
  • 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화
  • 트랜잭션이라는 작업 단위가 중요 -> 커밋 직전에 동기화

준영속 상태

준영속 상태

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

준영속 상태를 만드는 방법

  • em.detach(entity) : 특정 엔티티만 준영속 상태로 전환
  • em.clear() : 영속성 컨텍스트 전체 초기화
  • em.close() : 영속성 컨텍스트 종료

JPA는 엔티티에 기본 생성자가 있어야 한다.

JPA는 내부적으로 리플랙션을 사용해서 동적으로 객체를 생성한다.
그렇기 때문에 기본 생성자가 있어야 한다.

profile
지금부터 공부하고 개발한것들을 꾸준하게 기록하자.

0개의 댓글

관련 채용 정보