[JPA] 3장 영속성 관리

off_sujin·2022년 2월 5일
0

본 글은 김영한님의 <자바 ORM 표준 JPA 프로그래밍>을 읽고 공부한 내용을 정리한 글입니다.

  1. 엔티티 매니저 팩토리와 엔티티 매니저
  2. 영속성 컨텍스트란?
  3. 엔티티의 생명주기
  4. 영속성 컨텍스트의 특징
  5. 플러시
  6. 준영속

1. 엔티티 매니저 팩토리와 엔티티 매니저

엔티티 매니저 팩토리

  • 엔티티 매니저를 만드는 공장
  • 생성 비용이 크기 때문에 한 개만 만들어서 애플리케이션 전체에서 공유
  • 다른 스레드 간 공유 가능

엔티티 매니저

  • 엔티티와 관련된 모든 일 처리
  • 엔티티 매니저 팩토리에서 생성
  • 동시성 문제가 있으므로 스레드 간 공유 금지

2. 영속성 컨텍스트란?

  • 엔티티를 영구 저장하는 환경
  • 엔티티 매니저를 생성할 때 내부에 함께 만들어진다.
    em.persist(member); : 엔티티 매니저를 사용해서 회원 엔티티를 영속성 컨텍스트에 저장

3. 엔티티의 생명주기

비영속(new/transient)

  • 영속성 컨텍스트와 전혀 관계가 없는 상태
  • 객체를 생성한 상태
Member member = new Member();
member.setId("member1");
member.setUsername("회원1);

영속(managed)

  • 영속성 컨텍스트에 저장된 상태
    em.persist(member); : 객체를 저장
  • em.find()나 JPQL을 사용해서 조회한 엔티티도 포함

준영속(detached)

  • 영속성 컨텍스트에 저장되었다가 분리된 상태
    em.detach(member); : 회원 엔티티를 영속성 컨텍스트에서 분리
    em.clear();, em.close(); : 영속성 컨텍스트가 관리하던 엔티티 -> 준영속 상태

삭제(removed)

  • 삭제된 상태
    em.remove(member); : 객체 삭제

4. 영속성 컨텍스트의 특징

  • 영속 상태는 식별자 값(@Id로 테이블의 기본 키와 매핑한 값) 이 반드시 있어야한다.
  • 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 DB에 반영 : 플러시

영속성 컨텍스트의 장점

1차 캐시

  • 영속성 컨텍스트 내부에 있는 캐시, 영속 상태의 엔티티를 모두 저장하고 있다.
  • <식별자, 엔티티 인스턴스> Map
  • 1차 캐시에서 조회 : 성능상 이점
Member member = new Member();
member.setId("member1");
member.setUsername("회원1);

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

//1차 캐시에서 조회
Member findMember = em.find(Member.class, "member1");

1차 캐시에 찾는 엔티티가 있으면 DB를 조회하지 않고 메모리에 있는 1차 캐시에서 엔티티를 조회한다.

  • 데이터베이스에서 조회

    찾는 엔티티가 1차 캐시에 없으면 데이터베이스를 조회해서 엔티티를 생성
    -> 생성한 엔티티를 1차 캐시에 저장한 후(영속 상태) 조회한 엔티티를 반환한다.

동일성 보장

Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");

a == b // True

1차 캐시에 있는 같은 엔티티 인스턴스를 반환하기 때문에 동일성을 보장한다.

동일성 : 실제 인스턴스가 같다.
동등성 : 인스턴스는 다를 수 있지만 인스턴스의 값이 같다.

트랜잭션을 지원하는 쓰기 지연


엔티티 매니저는 트랜잭션을 커밋하기 직전까지 내부 쿼리 저장소에 SQL을 모아두고, 트랜잭션을 커밋할 때 모아둔 쿼리를 DB에 보낸다.

변경 감지

  • 엔티티의 변경사항을 DB에 자동으로 반영하는 기능

    • JPA는 엔티티를 영속성 컨텍스트에 보관할 때 스냅샷을 보관한다.
    • 플러시 시점에 스냅샷과 엔티티를 비교해 변경된 엔티티를 찾는다.
    • 변경된 엔티티가 있으면 수정 쿼리를 생성하고 쓰기 지연 SQL 저장소에 보낸다.
  • 변경 감지는 영속 상태의 엔티티에만 적용된다.

  • JPA 기본 전략은 엔티티의 모든 필드를 업데이트한다.

지연 로딩

실제 객체 대신 프록시 객체를 로딩해두고 해당 객체를 실제로 사용할 때 영속성 컨텍스트를 이용한다.

5. 플러시

  • 영속성 컨텍스트의 변경 내용을 DB에 반영한다.(동기화)
  • 플러시 과정
    • 변경 감지가 동작하여 수정된 엔티티를 찾고 수정 쿼리를 만들어 쓰기 지연 SQL 저장소에 등록한다.
    • 쓰기 지연 SQL 저장소의 쿼리를 DB에 전송한다.

6. 준영속

  • 영속 상태 -> 준영속 상태

    • em.detach(entity) : 특정 엔티티만 준영속 상태로 전환한다.
      -1차 캐시와 SQL 저장소에 있는 엔티티 정보를 삭제한다.
    • em.clear() : 영속성 컨텍스트 초기화
    • em.close() : 영속성 컨텍스트 종료
  • 준영속 상태 -> 영속 상태

merge()
- 영속성 컨텍스트 조회 -> 데이터 베이스 조회 -> 새로운 엔티티 생성
- 준영속, 비영속을 신경쓰지 않고 병합
- save or update 기능을 수행

? : 준영속 상태가 되면 1차 캐시에 있는 엔티티 정보를 삭제하는데 왜 1차 캐시에서 엔티티를 찾아보는건지 궁금..
profile
학습 중..

0개의 댓글