본문 바로가기
[ ORM ]/JPA

[ JPA ] 영속성 컨텍스트(Persistence Context) 개념 정리 및 사용법

by 환이s 2024. 2. 21.

 


영속성 컨텍스트(Persistence Context)

 

영속성 컨텍스트(Persistence Context)엔티티를 영구 저장하는 환경이라는 뜻으로,

애플리케이션과 데이터베이스 사이에서 객체를 보관하는 가상의 데이터베이스 같은 역할을 한다.

 

이 과정에서 가상의 데이터베이스에 저장할 때 EntityManager를 사용하는데 개념은 아래에서 다루겠다.

 

영속성 컨텍스트는 JPA를 이해하는데 가장 중요한 용어이다.

 

간단하게 정리하면 다음과 같다.

 

  • 영속성 컨텍스트는 논리적인 개념
  • 눈에 보이지 않음
  • 엔티티 매니저를 통해 영속성 컨텍스트에 접근

즉, EntityManager로 Entity를 저장하거나 조회하면

EntityManager는 영속성 컨텍스트에 Entity를 보관하고 관리한다.

 

EntityManageFactory emf = Persistence.createEntityManagerFactory("persistence-name");

EntityManage em = emf.createEntityManager();

em.persist(member);

 

위에 코드를 보면 persist() 메서드는 단순히 Member Entity를 저장한 것 같지만

정확히 말하면 EntityManager를 사용해서 Member Entity를 영속성 컨텍스트에 저장한 것이다.

 

그렇다면 지금까지 설명할 때 자주 등장하는 EntityManager의 역할에 대해 알아보자.


EntityManager

 

EntityManagerEntity를 저장하는 메모리상의 데이터베이스라고 볼 수 있다.

Entity를 저장하고, 수정하고, 삭제하고, 조회하는 등 Entity와 관련된 모든 일을 한다. 

 

하지만 EntityManagerFactory와 달리 Thread-Safe하지 않기 때문에

동시성 문제가 발생할 수 있다.

 

그래서 EntityManager스레드간에 공유를 절대로 해서는 안된다.

일반적으로 EntityManager@PersistenceContext로 Spring이 관리해주는 방식으로 사용한다.

 

@PersistenceContext를 사용해서 EntityManager를 주입받으면

Spring에서 EntityManagerProxy로 감싼 EntityManager를 생성해서

주입해주기에 Thread-Safe를 보장한다.

 

@PersistenceContext
private EntityManager entityManager;

 

 


Entity의 생명주기

 

Entity에는 4가지 상태가 존재한다.

 

  • 비영속(new/transient) : 영속성 컨텍스트와 전혀 관계가 없는 상태
//객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");

 

  • 영속(managed) : 영속성 컨텍스트에 저장된 상태
//객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

//객체를 저장한 상태(영속)
em.persist(member);

 

  • 준영속(detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태
//회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태
em.detach(member);

//영속성 컨텍스트를 완전히 초기화
em.clear();

//영속성 컨텍스트를 종료
em.close();

 

  • 삭제(removed) : 삭제된 상태
//객체를 삭제한 상태(삭제)
em.remove(member);

 


영속성 컨텍스트의 특징

 

  • 영속성 컨텍스트와 식별자 값
    • 영속성 컨텍스트는 Entity를 식별자 값(@Id)으로 구분한다.
    • 따라서 영속 상태는 식별자 값이 반드시 있어야 한다.
    • 영속성 컨텍스트에 데이터를 저장하고 조회하는 모든 기준은 기본 키 값이다.
  • 트랜잭션을 지원하는 쓰기 지연
    • Entity 값을 변경하면 DB에 바로 업데이트를 하지 않는다.
    • 트랜잭션 내부에서 영속 상태의 Entity의 값을 변경하면 Insert Query들은 DB에 바로 보내지 않고 Query 저장소에 쿼리문들을 생성해서 쌓아둔다.
      • 플러시(Flush) : 플러시는 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영하는 것을 말한다.
    • 이후 EntityManager의 Flush나 트랜잭션의 commit을 통해 보내지게 된다.
  • 1차 캐시에 저장 및 조회
    • 영속성 컨텍스트는 내부에 Entity를 저장하는 캐시를 가지고 있는데 이것을 1차 캐시라고 한다.
    • 영속 상태의 Entity는 데이터베이스에 저장되기 전(트랜잭션 호출 전)까지 모두 이곳에 저장된다.
    • Entity 조회 시 1차 캐시에서 먼저 찾고 만약 존재하지 않으면 데이터베이스를 조회한다.
    • 이러한 기능으로 성능상에 이점을 누릴 수 있다.

 

  • 동일성 보장
    • Entity가 1차 캐시에 저장되어 있기 때문에, 같은 식별자(@Id)에 대한 Entity는 매번 같은 인스턴스에 접근할 수 있다.
동일성 비교 : 실제 인스턴스가 같고, ==을 사용해 비교한다.
동등성 비교 : 실제 인스턴스는 다를 수 있지만 인스턴스가 가지고 있는 값이 같다. equals() 메서드로 비교한다.

 

  • 변경 감지(Dirty Checking)
    • Flush 시점에서 Entity와 스냅샷을 비교해 변경된 Entity가 있다면 쓰기 지연 SQL 저장소에 보낸다.
    • 따로 Entity 수정에 대한 메서드가 필요 없다.

 

 

  • 지연 로딩(Lazy Loading)
    • JPA에서는 데이터를 조회할 때 즉시 로딩(EAGER)과 지연 로딩(LAZY) 두 가지 방식이 있다.
    • 로딩(EAGER) 방식은 즉시 로딩은 데이터를 조회할 때 연관된 데이터까지 한 번에 불러오는 것이고, (Join)
    • 지연 로딩(LAZY) 방식은 필요한 시점에 연관된 데이터를 불러오는 것이라고 할 수 있다.(select)

마치며

 

오늘은 영속성 컨텍스트의 개념 정리 및 사용법에 대해 알아봤습니다.

다음 포스팅에서 뵙겠습니다.

 

위 포스팅 글은 김영한님의 자바 ORM 표준 JPA 프로그래밍-기본편을 참고했습니다.

 

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

JPA 를 공부하고 책을 보며 어려웠던 내용을 위주로 먼저 보았습니다. 옆에서 1:1 과외해주는 것 같이 생생하고 이해 잘되는 설명, 예제(코드)가 너무 좋았습니다. 어느 것 하나 애매함없이 모두

www.inflearn.com

 

728x90

'[ ORM ] > JPA' 카테고리의 다른 글

[ JPA ] 상속 관계 매핑  (59) 2024.03.18
[ JPA ] 다양한 연관관계 매핑  (57) 2024.03.13
[ JPA ] 연관관계 매핑 기초  (74) 2024.03.07
[ JPA ] Entity Mapping  (77) 2024.02.26
[ JPA ] JPA 소개  (59) 2024.02.15