y1551463

JPA - 영속성 컨텍스트 1

JPA영속성컨텍스트
a month ago
·
5 min read

영속성 컨텍스트

  • 고유 ID를 갖는 모든 영속 객체 인스턴스에 대한 집합

  • 영속성 컨텍스트 내에서 영속 객체에 대한 생명주기가 관리된다

    • EntityManager의 메서드를 이용

  • 영속성 컨텍스트는 어플리케이션과 DB 사이에 위치

  • 영속 객체에 대한 정보(데이터)는 영속성 컨텍스트 내부의 1차 캐시에서 관리된다

트랜잭션이 시작되고 EntityManager를 통해 영속성 컨텍스트에 객체가 올라가면

1차 캐시에 해당 영속 객체가 등록이된다 (영속 객체의 고유 ID / 엔티티 객체 / 스냅샷)

영속 객체가 올라간 상태는 아직 insert 작업이 처리된 것은 아니다

// EntityManager를 통해 가져온 트랜잭션을 시작
tx.begin();

try { // persist, commit 과정에서 예외가 발생하면 rollback
      em.persist(Customer.sample()); // 영속성 컨텍스트에 객체를 등록

      tx.commit();

} catch (Exception e) {
          tx.rollback();

} finally {
           em.close();
}

/*
persist() 엔티티 객체를 영속성 컨텍스트에 저장한다
해당 엔티티 객체는 영속 상태로 전환된다
영속 상태로 전환된 엔티티 객체는 1차 캐시에 저장되고 트랜잭션이 커밋되면 데이터베이스에 동기화된다
persist()는 객체를 "JPA 관리 상태"로 만드는 중요한 메서드
*/

tx.begin();
try { // persist, commit 과정에서 예외가 발생하면 rollback
      Customer customer = new Customer("ID0002", "kim");
      em.persist(customer); // insert 실행되지 않고 1차 캐시에 저장된다
      em.persist(customer);

      tx.commit(); // insert 실행된다
} catch (Exception e) {
          tx.rollback();
} finally {
           em.close();
}

/*
persist()를 호출한다고 해서 바로 삽입 쿼리가 발생하지 않고 
우선 영속성 컨텍스트 내부의 1차 캐시에 등록된다
commit 시점에 발생한다
즉 최종적으로 insert는 하나의 행에 대해서만 발생한다
*/
// EntityManager를 통해 가져온 트랜잭션을 시작
tx.begin();

try { // persist, commit 과정에서 예외가 발생하면 rollback
      em.persist(Customer.sample());
      Customer foundCustomer = em.find(Customer.class, "ID0001");
      foundCustomer.setName("choi");

      tx.commit();
} catch (Exception e) {
          tx.rollback();
} finally {
          em.close();
}

/*
이미 영속 상태로 전환된 영속 객체가 1차 캐시에 올라가 있는 상태이기 때문에
조회 쿼리는 발생하지 않음
그리고 트랜잭션 내에서 해당 영속 객체의 변화를 감지하고 commit 시점에 수정 쿼리를 날림
*/
tx.begin();
try { // persist, commit 과정에서 예외가 발생하면 rollback
      Customer customer = new Customer("ID0002", "kim");
      em.persist(customer); // insert 실행되지 않고 1차 캐시에 저장된다

      Customer foundCustomer = em.find(Customer.class, "ID0002"); 
      // 위 코드를 통해 캐시에 올라간 영속 객체를 반환해준다
      

      tx.commit(); // insert 실행된다
} catch (Exception e) {
          tx.rollback();
} finally {
          em.close();
}

/*
persist()를 통해 캐시에 올린 객체를 find()로 호출을 하면 조회 쿼리가 발생하지 않는다
이미 캐시에 올라갔기 때문에 캐시에 저장된 영속 객체를 반환해주기 때문
(찾고자 하는 영속 객체가 1차 캐시에 등록되어 있다면 해당 영속 객체를 반환하고 없다면 조회 쿼리)
*/

- 컬렉션 아티클