JPA

[JPA] 영속성 컨텍스트

감자b 2024. 12. 29. 02:45

영속성 컨텍스트

엔티티 매니저를 통해서 접근 가능한 논리적인 개념을 의미한다.

→ 엔티티 매니저를 생성하면 내부적으로 PersistenceContext(영속성 컨텍스트) 생성, 스프링 프레임워크 같은 컨테이너 환경에서는 엔티티 매니저와 영속성 컨텍스트가 N:1 관계

외부에서 EntityManager를 주입받는 경우 주입된 EntityManager는 싱글톤

→ 스프링 프레임워크는 프록시 EntityManager를 주입 → 해당 엔티티 매니저를 호출하면 데이터베이스 트랜잭션과 관련된 진짜 EntityManager 호출함으로써 동시성 문제를 해결


엔티티의 생명 주기

 

  • 비영속(new) : 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
Member member = new Member();
  • 영속(managed) : 영속성 컨텍스트에 관리되는 상태
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

em.persist(member); //실제로 DB에 저장되는 것은 아니고 영속성 컨텍스트에서 관리

그럼 데이터베이스에 저장되는 시점은?

플러시(영속성 컨텍스트의 변경 내용을 동기화)가 일어날 때 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영

(영속성 컨텍스트를 비우는 것이 아니라 변경 내용을 동기화 하는 것)

em.persist(E) → 영속성 컨텍스트에 등록할 뿐 쿼리가 나가지 않음.

  • 플러시가 발생되는 경우 (쓰기 지연 SQL 저장소에 등록된 쿼리를 반영)
    1. em.flush() 호출
    2. 트랜잭션을 커밋하는 경우
    3. JPQL 쿼리를 실행하는 경우
  • 준영속(detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태
em.detach(member); // 특정 엔티티 준영속 상태로 변경
em.clear(); // 영속성 컨텍스트 초기화
em.close(); // 영속성 컨텍스트 종료
  • 삭제(remove) : 영속성 컨텍스트에서 삭제된 상태
em.remove(member);

 

영속성 컨텍스트의 이점

  1. 동일성을 보장
  2. 1차 캐시 활용 가능
  3. 트랜잭션을 지원하는 쓰기 지연
  4. 변경 감지(Dirty chekcing)
  5. 지연 로딩이 가능

예를 들어 다음과 같은 코드가 있다고 하자.

Member member = new Member();
member.setId("member1"); 
member.setUsername("회원1");

em.persist(member); //1차 캐시에 등록
Member findMember = em.find(Member.class, "member1"); //DB가 아닌 1차 캐시에서 조회

 

 

해당 member1의 아이디를 가진 멤버를 조회할 때 em.persist를 통해 1차 캐시에 등록을 해놓았으므로 멤버를 DB에서 조회하는 것이 아닌 영속성 컨텍스트에서 조회할 수 있다.

또한 해당 멤버를 여러 번 조회를 하여도 그 인스턴스들은 동일성을 보장하고, 해당 멤버의 이름이 회원1에서 회원2로 변경이 되었을 때 update를 호출하지 않아도 update 쿼리가 나가게 된다.

1차 캐시에 member1이 등록이 될 때 쓰기 지연 저장소에 insert 쿼리를 쌓아두고 트랜잭션이 커밋되는 순간에 해당 저장소에 존재하는 쿼리들이 한 번에 DB에 반영된다는 장점을 가지고 있다.


참고

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 강의 | 김영한 - 인프런

김영한 | JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., 실무에서도

www.inflearn.com