본문 바로가기

JPA

Entity Manager, 영속성 컨텍스트

JPA 는 java 와 DB 사이에서 DB 의 데이터와 Java Application 의 객체를 연결시키는 ORM 기술이다.

 

 

 

JPA 를 사용하기 위해서는 Xml 을 작성해야한다.

META-INF/persistance.xml 로 위치는 고정이며, 아래와 같이 작성한다.

<persistence-unit name="hello">
        <properties>

        </properties>
    </persistence-unit>

이는 보통 DB 마다 생성하게 된다.

 

 

우리는 에플리케이션 단에서 이 persistence unit 하나로 하나의 Entity Factory 를 만들 수 있다.

 

Entity Manager

  • DB 의 데이터들은 에플리케이션에서 Entity 라는 단위로 관리된다.
  • JPA 는 하나의 요청마다 하나의 Entity manager 을 생성해준다.
  • 이 Entity Manager 는 Entity 를 관리하는 일을 수행한다.
  • JPA 의 모든 데이터 변경은 이 Entity Manager 가 수행해주는데, 이 작업은 무조건 트랜잭션 안에서 수행되어야 한다.
  • Entity Manager 는 스레드간 공유하면 안된다.
  • Entity Manager 는 Entity Manager Factory 가 생성해준다.

 

entity manager 는 스레드간 공유되면 안된다 그랬는데, 에초에 entity manager 객체는 Thread-safe 하지 않다.

여기서 Spring Container 는 Entity manager 객체를 사용할 때, proxy 패턴을 이용하여 주입해줌으로서 thread-safe 를 보장해준다.

www.baeldung.com/hibernate-entitymanager

 

Guide to the Hibernate EntityManager | Baeldung

Have a look at the EntityManager class and its use in Hibernate

www.baeldung.com

stackoverflow.com/questions/24643863/is-entitymanager-really-thread-safe

 

Is EntityManager really thread-safe?

I'm talking about the basic usage here: @Stateless public class BookServiceBean implements BookService { @PersistenceContext EntityManager em; public void create(Book book) { this.em.persist(b...

stackoverflow.com

 

Entity Manager Factory

  • persistence.xml 의 persistence-unit 에 대응하는 Entity Manager Factory 를 생성할 수 있다.
  • 요청마다 Entity Manager 를 생성해주는 역할을 한다.
  • 애플리케이션 전체에서 하나만 생성하여 모든 스레드가 공유한다.

 

이를 코드로 작성해보면 다음과 같다.

 

    public static void main(String[] args) {
        // 엔티티 메니저 팩토리 생성
        // 엔티티 메니저 팩토리는 하나만 생성
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        // 엔티티 메니저 생성
        // 트랜잭션마다 엔티티 매니저 생성
        EntityManager em = emf.createEntityManager();

        // JPA 는 무조건 트랜직션 단위로 실행해야함.
        EntityTransaction transaction = em.getTransaction();
        transaction.begin();

		// 쿼리 작업
        
        emf.close();
    }

 

여기서 EntityManagerFactory, EntityManager 를 뜯어보면 알겠지만, 둘 다 인터페이스이다. JPA 인터페이스이며,

보통 우리는 Hibernate 를 사용하므로 EntityManagerFactory 의 구현체 SessionFactory, EntityManager 의 구현체 Session 을 생성하게 된다.

 

 

 

영속성 컨텍스트 (persistence context)

  • entity 의 영속성을 저장하는 환경 이라는 뜻.

영속성 컨텍스트의 공식 정의는 아래와 같다.

An EntityManager instance is associated with a persistence context. A persistence context is a set of entity instances in which for any persistent entity identity there is a unique entity instance. Within the persistence context, the entity instances and their lifecycle are managed. The EntityManager API is used to create and remove persistent entity instances, to find entities by their primary key, and to query over entities.

https://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html

 

  • Hibernate 같은 JPA 구현체는 영속성 컨텍스트를 이용하여 엔티티의 생명주기를 관리한다.
  • 개발자가 영속성 컨텍스트를 뜯어볼 수 없기 때문에 어느정도 추상적인 개념으로 이해가 필요하다.
  • JPA 표준 스펙에 정의되어 있다.
데이터가 DB 와 같은 공간에 저장되는 것을 영속화 된다고 하며, DB 의 이런 특성을 영속성이라 한다.
  • 직관적으로 이해하려면 하나의 Entity Manager 안에 영속성 컨텍스트가 있으며, 애플리케이션과 DB 사이의 캐시 라고 생각하면 될 듯하다.

코드상에서 @PersistenceContext 으로 엔티티 메니저를 선언하면, 스프링 컨테이너가 Thread-safe 한 영속성 컨텍스트를 가진 entity manager 를 주입하게 된다.

 

또는 @PersistenceContext(type = PersistenceContextType.EXTENDED) 옵션을 주면, 여러 스레드가 공유하는 영속성 컨텍스트 (extended-scoped persistence context) 를 만들 수 있다.

확장된 EntityManager가 되어 스레드세이프하지 않으므로 스프링이 관리하는 싱글톤 빈처럼 동시에 접근하게 되는 컴포넌트에서는 사용하지 말아야 한다. 확장된 EntityManager는 상태를 가진 컴포넌트에서만 사용하도록 만들어졌다. 예를 들면 현재 트랜잭션에 묶인 것이 아니라 어플리케이션에 완전히 묶인 EntityManager의 생명주기를 가진 세션에 존재하는 상태를 가진 컴포넌트들이다.

www.baeldung.com/jpa-hibernate-persistence-context#extended_persistence_context

 

JPA/Hibernate Persistence Context | Baeldung

Learn about Persistence Context with Hibernate

www.baeldung.com

 

blog.outsider.ne.kr/890

 

[Spring 레퍼런스] 14장 객체 관계 매핑 (ORM) 데이터 접근 #2 :: Outsider's Dev Story

이 문서는 개인적인 목적이나 배포하기 위해서 복사할 수 있다. 출력물이든 디지털 문서든 각 복사본에 어떤 비용도 청구할 수 없고 모든 복사본에는 이 카피라이트 문구가 있어야 한다.14.4 JDO

blog.outsider.ne.kr

 

 

 

 

 

 

영속성 컨텍스트와 엔티티 생명주기

엔티티 생명주기에는 4가지 상태가 있다.

 

  • 비영속
    • 객체를 생성한 상태
    • 영속성 컨텍스트를 사용하지 않은 new 객체생성
  • 영속
    • 비영속 상태의 객체를 persist() 메서드를 통해 엔티티 메니저에 영속화하도록 등록된 상태
  • 준영속
    • detach() 메서드를 통해 영속 상태에서 해제한 상태
    • clear(), close() 를 통해 트랜직션이 종료되거나 Entity Manager 가 종료되었을때 영속 상태에 있던 엔티티가 준영속 상태가 될 수 있음.
    • 비영속 상태와 다른점은, 준영속 상태는 적어도 한번 영속상태가 되었다가 해제된 것이므로, 식별자가 항상 존재한다.
  • 삭제
    • remove() 메서드로 데이터를 삭제하도록 하는 상태

 

'JPA' 카테고리의 다른 글

JPQL - Select  (0) 2021.04.23
JPQL  (0) 2021.04.22
영속성 컨텍스트를 쓰면 좋은점  (0) 2021.04.14