해당 글은 김영한 님의 자바 ORM 표준 JPA 프로그래밍을 참고하여 작성한 글입니다.
✅ 영속성 관리
▶ 엔티티 매니저 팩토리와 엔티티 매니저
- 엔티티 매니저 팩토리(EntityManagerFactory): 엔티티 매니저를 만드는 공장
- 엔티티 매니저(EntityManager): 엔티티를 관리하는 관리자, 엔티티를 저장, 수정, 삭제, 조회하는 등 엔티티와 관련된 모든 일을 처리한다.
- 엔티티 매니저 팩토리를 생성하는 비용은 상당히 크지만, 반면에 엔티티 매니저를 생성하는 비용은 거의 들지 않는다.
- 엔티티 매니저 팩토리는 여러 스레드가 동시에 접근해도 안전하므로 다른 스레드 간 공유가 가능하지만, 엔티티 매니저는 여러 스레드가 동시에 접근하면 동시성 문제가 발생하므로 스레드 간 절대 공유해서는 안 된다.
▶ 영속성 컨텍스트(Persistence Context)란?
- "Entity를 영구 저장하는 환경"이라는 의미로, 눈에 보이지 않는 논리적인 개념이다. EntityManager를 통해 영속성 컨텍스트에 접근 및 관리할 수 있다.
▶ 엔티티의 생명주기
- 비영속(new/transient): 영속성 컨텍스트와 전혀 관계가 없는 상태
- 영속(managed): 영속성 컨텍스트에 저장된 상태, 영속성 컨텍스트에 의해 관리되는 상태
- 준영속(detached): 영속성 컨텍스트에 저장되었다가 분리된 상태, 영속성 컨텍스트가 관리하던 영속 상태의 엔티티를 관리하지 않게 된 상태
- 삭제(removed): 엔티티가 영속성 컨텍스트와 데이터베이스에서 삭제된 상태
// 객체를 생성: 비영속
Member member = new Member();
member.setId("memberA");
member.setUsername("회원1");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// 객체를 저장: 영속
em.persist(member);
// 객체를 분리: 준영속
em.detach(member);
// 객체를 제거: 삭제
em.remove(member);
▶ 영속성 컨텍스트의 이점
- 1차 캐시
- em.persist(member)로 객체를 영속화하면 EntityManager가 관리하는 1차 캐시에 객체를 저장한다. 실제 DB에 저장되는 시점은 트랜잭션이 Commit 될 때이므로 같은 트랜잭션에서 객체가 변경되는 정보들을 모아서 한 번에 쿼리를 날린다.
- 동일성 보장
- 같은 EntityManager에서 조회한 경우 동일한 객체이고, 다른 EntityManager에서 조회한 경우 다른 객체이다.
- 예: em.find(Member.class, "member1")를 반복해서 호출해도 영속성 컨텍스트는 1차 캐시에 있는 같은 엔티티 인스턴스를 반환한다. 같은 인스턴스면 동일성 비교는 참이 된다.
- 트랜잭션을 지원하는 쓰기 지연
- 엔티티 매니저는 하나의 트랜잭션을 기준으로 영속성 컨텍스트가 관리하는 객체에 변경된 정보들을 모아서 쓰기 지연 SQL 저장소에 각 SQL을 저장해 놓고, Commit 되는 순간 DB에 SQL을 보낸다.
- 변경 감지(Dirty Checking)
- 영속성 컨텍스트에서 관리하는 객체에 변경이 생긴 경우, 1차 캐시에 저장되어 있는 스냅샷과 비교 후 달라진 부분에 맞게 SQL을 생성해서 쓰기 지연 SQL 저장소에 저장한다. 그리고 Commit 되는 순간 Flush 한다.
▶ 영속성 컨텍스트 플러시, 초기화, 종료, 병합
- 플러시(flush()): 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다. (1차 캐시는 유지한다.)
- 플러시 방법
- em.flush()를 직접 호출한다.
- 트랜잭션 커밋 시 플러시가 자동 호출된다.
- JPQL 쿼리 실행 시 플러시가 자동 호출된다.
- 플러시 방법
- 초기화(clear()): 영속성 컨텍스트를 초기화한다. 해당 영속성 컨텍스트의 모든 엔티티는 준영속 상태가 된다.
- 종료(close()): 영속성 컨텍스트를 종료한다. 해당 영속성 컨텍스트의 영속 상태의 엔티티가 모두 준영속 상태가 된다.
- 병합(merge()): 준영속 상태의 엔티티를 다시 영속 상태로 변경한다.
📍 참고
'Programming > JPA' 카테고리의 다른 글
[JPA] 데이터베이스 스키마 자동 생성 (0) | 2024.07.25 |
---|---|
[JPA] 필드와 컬럼 매핑 - 엔티티(Entity) 매핑 (3) (0) | 2024.07.25 |
[JPA] 기본 키 매핑 - 엔티티(Entity) 매핑 (2) (0) | 2024.07.25 |
[JPA] 객체와 테이블 매핑 - 엔티티(Entity) 매핑 (1) (0) | 2024.07.25 |
[JPA] JPA 소개 (0) | 2024.07.25 |