JPA-2

HyeBin, Park·2022년 1월 4일
0
post-thumbnail

영속성 컨텍스트

  • 엔티티를 영구 저장하는 환경 EntityManager.persist(엔티티);

  • 엔티티 매니저로 엔티티를 저장하거나 영속성 컨텍스트에 엔티티를 보관하고 관리한다.

  • 논리적인 개념, 엔티티 매니저 생성시 하나가 만들어진다.

  • 여러 엔티티 매니저가 같은 영속성 컨텍스트에 접근할 수 있다.

    엔티티의 생명주기

  • 비영속 (new/transient) : 영속성 컨텍스트와 전혀 관계가 없는 상태

  • 영속 (managed) : 영속성 컨텍스트에 저장된 상태

  • 준영속 (detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태

  • 삭제 (removed) : 삭제된 상태

영속성 컨텍스트 특징

  • 엔티티를 식별자 값으로 구분한다. => 영속상태는 식별자 값이 반드시 있어야한다. 없으면 예외 발생
  • jpa는 보통 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 저장된 엔티티를 db에 반영 => flush()

엔티티 조회

  • 영속성 컨텍스트는 내부에 1차 캐시를 가지고 잇는데 엔티티는 모두 이곳에 저장된다 => 즉, Map이 있으면 키는 @Id로 매핑한 식별자고 값은 엔티티 인스턴스
  • find() 메소드 사용시 1차 캐시에서 엔티티를 찾고 여기에 없으면 db에서 조회한다.
  • db에서 조회할 경우 엔티티를 생성하고 1차 캐시에 저장한 후에 영속 상태의 엔티티를 반환한다.

영속 엔티티의 동일성 보장

  • 동일성(identity) : 실제 인스턴스가 같다. == 비교의 값이 같다.

  • 동등성(equality) : 실제 인스턴스는 다를 수 있지만 인스턴스가 가지고 있는 값이 같다.

Member a = entitymanager.find(Member.class, "m1");
Member b = entitymanager.find(Member.class, "m1");
System.out.println(a == b); // 동일성 비교, true 
  • entitymanager.find(Member.class, "m1")를 반복해서 호출해도 영속성 컨텍스트는 1차 캐시에 있는 같은 엔티티 인스턴스를 반환한다.

쓰기지연(transactional write-behind)

  • 엔티티 매니저는 트랜잭션을 커밋하기 내부 쿼리 저장소에 INSERT SQL을 모아둔다.
  • 그리고 commit할 때 모아둔 쿼리를 db에 보낸다.
  • commit하면 영속성 컨텍스트를 flush 한다. flush는 영속성 컨텍스트의 변경 내용을 db에 동기화하는 작업

변경 감지(dirty checking)

  • 엔티티의 변경사항을 db에 자동으로 반영하는 기능
  • 엔티티를 영속성 컨텍스트에 보관할때 최초 상태를 복사해서 저장해두는데 이것을 스냅샷이라 한다.
  • 그리고 플러시 시점에 스냅샷과 엔티티를 비교해서 변경된 엔티티를 찾는다.
  • 영속성 컨텍스트가 관리하는 영속 상태의 엔티티에만 적용된다.

엔티티 삭제

  • entitymanager.remove(0에 삭제 대상 엔티티를 넘겨주면 엔티티를 삭제한다. 호출하는 순간 영속성 컨텍스트에서 제거된다.
  • 삭제 쿼리를 쓰기 지연 sql 저장소에 등록한다.

flush()

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

flush 하는 방법

  • entitymanage.flush() 를 직접 호출한다. => 강제, 거의 사용하지 않는다.
  • 트랜잭션 커밋 시 플러시가 자동 호출된다.
  • JPQL 쿼리 실행 시 플러시가 자동 호출된다. => JPQL 실행시 SQL로 변환되어 DB에서 엔티티를 조회하는데 DB에 없으므로 조회가 되지 안흔다. 따라서 쿼리 실행 직전에 flush가 자동으로 호출된다.

플러시 모드 옵션

  • FlushModeType.AUTO : 커밋이나 쿼리를 실행할 때 플러시(기본값)
  • FlushMdoeType.COMMIT : 커밋할 때만 플러시

0개의 댓글