본문 바로가기

Back-End/JPA

JPA - 영속성 컨텍스트(Entity)

영속성 컨텍스트(PersistenceContext)

Entity 객체영속성 상태로 관리하는 일종의 캐시 역할을 하는 공간으로 여기에 저장된 Entity는 데이터베이스와 자동으로 동기화 되며 같은 트랜잭션 내에서는 동일한 객체가 유지된다.

Entity

데이터베이스에서 Entity란 저장할 수 있는 데이터의 집합을 의미

  • JPA에서 Entity데이터베이스의 테이블을 나타내는 클래스를 의미함.

Entity 생명주기

Item item = new Item(); // 1
item.setItemNm("테스트 상품");	

EntityManager em = entityManagerFactory.createEntityManager(); // 2
EntityTransaction transaction = em.getTransaction(); // 3
	
transaction.begin();		
em.persist(item); // 4-1
em.flush(item). // 4-2 (DB에 SQL 보내기/commit시 자동수행되어 생략 가능함)
transaction.commit(); // 5

em.close();	// 6

1️⃣  영속성 컨텍스트에 담을 상품 엔티티 생성
2️⃣  엔티티 매니저 팩토리로부터 엔티티 매니저를 생성
3️⃣  데이터 변경 시 무결성을 위해 트랜잭션 시작
4️⃣  영속성 컨텍스트에 저장된 상태, 아직 DB에 INSERT SQL 보내기 전
5️⃣  트랜잭션을 DB에 반영, 이 때 실제로 INSERT SQL 커밋 수행
6️⃣  엔티티 매니저와 엔티티 매니저 팩토리 자원을 close() 호출로 반환
  • 비영속(new)
    • 영속성 컨텍스트가 모르는 새로운 상태
    • 데이터베이스와 전혀 연관이 없는 객체
  • 영속
    • 영속성 컨텍스트에 저장되고 관리되고 있는 상태
    • 데이터베이스와 동기화 되는 상태
  • 준영속
    • 영속성 컨텍스트에 저장되었다가 분리되어 더 이상 기억하지 않는 상태
  • 삭제
    • 영속성 컨텍스트에 의해 삭제로 표시된 상태
    • 트랜잭션이 끝나면 데이터베이스에서 제거
  • JPA 관점에서 순서대로 요약정리
    • new > 비영속상태 > persist() or merge() > 영속성 컨텍스트에 저장된 상태 > flush() > DB에 쿼리가 전송된 상태 > commit() > DB에 쿼리가 반영된 상태

Entity 상태

엔티티 상태는 비영속, 영속, 준영속, 삭제 상태로 나뉘며 영속 상태일 때만 JPA의 영소성 컨텍스트가 데이터를 관리한다.

1. 비영속 : 영속성 컨텍스트와 전혀 관계가 없는 상태

// 객체를 생성하고 영속성 컨텍스트에 저장하지 않은 상태
Tutor tutor = new Tutor(1L, "병천", 100);

2. 영속 

public static void main(String[] args) {
    // EntityManagerFactory 생성
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("test");
    // EntityManager 생성
    EntityManager em = emf.createEntityManager();
    // Transaction 생성
    EntityTransaction transaction = em.getTransaction();

    // 트랜잭션 시작
    transaction.begin();

    try {
        // 비영속
        Tutor tutor = new Tutor(1L, "병천", 100);

        System.out.println("persist 전");
        // 영속(저장) -> 영속 상태가 된다.
        em.persist(tutor);
        System.out.println("persist 후");

        // transaction이 commit되며 실제 SQL이 실행된다.
        transaction.commit();
    } catch (Exception e) {
        // 실패 -> 롤백
        e.printStackTrace();
        transaction.rollback();
    } finally {
        // 엔티티 매니저 연결 종료
        em.close();
    }
    
    emf.close();

}
  • 트랜잭션 Commit 시점에 SQL이 실행된다.

3. 준영속

  • detach는 영속성 컨텍스트에서 지운다, 준영속 상태로 만듦.
  • 영속성 컨텍스트가 제공하는 기능을 사용하지 못함.
  • 준영속 상태로 만드는 방법
    • em.detach()
      • 특정 entity만 준영속 상태로 변경
    • em.clear()
      • 영속성 컨텍스트를 초기화 한다.
    • em.close()
      • 영속성 컨텍스트를 종료한다

4. 삭제


persist()의 역할

persist() 메서드는 비영속 상태의 엔티티를 영속성 컨텍스트에 추가하여 영속 상태로 전환한다.

  1. 영속성 컨텍스트에 엔티티 저장
    • persist()를 호출하면 해당 엔티티가 영속성 컨텍스트에 등록된다.
    • 이후부터 JPA는 해당 엔티티를 관리한다.
  2. 트랜잭션 커밋 시 데이터베이스에 저장
    • persist()는 즉시 데이터베이스에 저장하지 않는다.
      • 참고) 기본 키 값을 자동으로 생성하는 전략 중 IDENTITY 전략은 persist()후 바로 쿼리에 저장됨
    • 트랜잭션이 커밋되거나 flush될 때 데이터베이스에 INSERT 쿼리가 실행된다.
  3. 변경 감지 적용
    • 영속성 컨텍스트에 관리되는 동안 해당 엔티티의 변경 사항을 감지하여 필요한 경우 DB에 업데이트함.