본문 바로가기
IT/Spring boot

[Spring boot] EntityManager & JPA Entity Life Cycle

by kyu-nahc 2024. 8. 11.
반응형

Entity Manager

EntityManagerPersistent Context 내에서 Entity들을 보관 관리한다.

Persistent Context와 JPA에 대한 내용은 아래 포스팅에 자세히 나와있다.

 

 

[Spring boot] Persistent Framework & JPA의 등장

데이터 영속성Persistence(영속성)은  데이터들이 프로그램이 종료되어도 사라지지 않고, 어떤 곳에 저장되는 개념을 뜻한다.물리적인 저장소를 이용해 프로그램의 상태와 상관없이 데이터를 저

kyu-nahc.tistory.com

 

EntityManager는 JPA에서 제공하는 interfaceSpring Bean으로 등록되어 있어

Autowired 또는 생성자 주입으로 사용할 수 있다.

Query Method, Simple JPA Repository

직접적으로 EntityManager를 사용하지 않도록 한번 더 감싸준 것이다.

Spring JPA에서 제공하지 않는 기능을 사용하거나, 별도로 Customizing을 해야 한다면

EntityManager를 직접 받아서 처리해야 한다.

추가적으로 EntityManager는 Entity Cache를 가지고 있다.

 

Entity Manager의 CRUD와 주요 메소드는  다음과 같다.

  • Create
    Entity를 Persistent Context에 저장
  • Read
    1차 캐시에서 Entity를 조회

    1차 캐시에 Entity가 없을 경우 데이터베이스를 조회하여 Entity 생성
  • Update
    Read 작업을 통해 조회된 Entity 객체의 값을 변경
  • Delete
    Persistent Context에서 삭제
  • merge
    준영속 상태의 Entity를 다시 영속 상태로 변경
  • flush
    Persistent Context 변경 내용을 데이터베이스에 반영

    (호출 시 변경 필드에 의해 자동으로 Update / Insert 진행)
  • clear
    Persistent Context를 완전히 초기화
  • close
    Persistent Context를 종료
  • detach
    특정 Entity를 준영속 상태로 전환

 

Entity Life Cycle

 

Entity의 Life Cycle을 살펴보면 위의 그림처럼 나타낼 수 있다.

여기서 상태는 New / Detached / Managed / Removed 4가지로 나뉜다.

각 상태를 살펴보면 다음과 같다.

 

비영속 ( New / Transient ) 상태

Persistent Context와 전혀 관계가 없는 상태로 순수한 Java 객체 상태이다.

Entity Manager가 관리하지 않는 상태라고 할 수 있다.

즉 Entity 객체를 생성하였지만, 아직 Persistent Context에 저장하지 않은 상태를 의미한다.

 

영속 ( Managed ) 상태

Persistent Context에 저장된 상태이다.

Entity가 Persistent Context에 의해 관리됨을 의미하고,

PK(Primary Key)을 통해 필요한 Entity 객체를 꺼내 사용할 수 있다.

영속 상태가 되었다고 바로 DB에 값이 저장되지 않고,

Transaction Commit 시점에 Persistent Context에 있는 정보들을 DB에 Query로 보낸다.

 

준영속 ( Detached ) 상태

Persistent Context에 저장되었다가 분리된 상태이다.

Entity를 준영속 상태로 만들려면 detach()를 호출해야 하며,

준영속 상태에서는 1차 캐시, 쓰기 지연, 변경 감지, 지연 로딩을 포함한

Persistent Context가 제공하는 어떠한 기능도 동작하지 않는다.

 

준영속 ( Removed ) 상태

Persistent Context와 DB에서 해당 Entity를 삭제한 상태로,

삭제된 객체는 Persistent Context에 존재하지 않는다.

 

다음과 같은 상태의 변화를 코드롤 통해 살펴보면 다음과 같다.

@RequiredArgsConstructor
public class Demo {
    
    // 생성자 주입으로 Entity Manager 추가
    private final EntityManager entityManager;

    private void EntityManagerTestMethod(){
        
        // 객체만 생성한 비영속 상태
        Member member = new Member();
        
        // 객체를 저장한 영속 상태
        entityManager.persist(member);
        
        // detach()를 통해 특정 Entity 영속 -> 준영속 상태로 변경
        entityManager.detach(member);
        
        // clear()를 통해 관리되고 있던 Entity 준영속 상태로 변경
        entityManager.clear();
        
        // close()도 마찬가지로 관리되고 있던 Entity 준영속 상태로 변경
        entityManager.close();
        
        // detach() 된 Entity merge() 하면 준영속 -> 영속 상태로 변경
        entityManager.merge(member);
        
        // Persistent Context / 데이터베이스에서 삭제 상태
        entityManager.refresh(member);
    }
}

 

 

위의 Entity Life Cycle을 참고하여 Persistent Context의 특징 및 이점을 정리하면 다음과 같다.

 

Persistent Context 특징

  • Persistent Context는 Entity를 식별자 값으로 구분한다.
  • 영속 상태반드시 식별자 값이 있어야 한다.
  • Persistent Context에 저장된 Entity는 Transaction을 Commit 하는 순간,
    새로 저장된 Entity를 DB에 반영한다.

Persistent Context 사용 이점

  • 1차 캐시
    1차 캐시(Persistent Context 내부 캐시)에 key=@Id: value=Entity로 저장한다.
  • 동일성 보장
    DB에서 조회한 데이터를 기반으로 새로운 Entity를 생성하는 것이 아닌
    1차 캐시에서 삽입/조회해서 동일성 보장한다.
  • Transaction을 지원하는 쓰기 지연
    persist()를 호출했을 때, 바로 insert 쿼리를 보내는 것이 아니라,
    Persistent Context에 집어넣고 Transaction Commit 하기 직전까지
    '쓰기 지연 SQL 저장소'insert 쿼리문을 쌓아둔다.
  • 변경 감지 (Dirty checking)
    Entity의 변경 사항을 DB에 자동으로 반영해 준다.
  • 지연 로딩(Lazy Loading)
    연관 관계 매핑되어 있는 Entity 조회 시 Proxy를 반환해서 쿼리를 필요할 때 보낸다.
반응형

loading