Entity Manager
EntityManager는 Persistent Context 내에서 Entity들을 보관 관리한다.
Persistent Context와 JPA에 대한 내용은 아래 포스팅에 자세히 나와있다.
EntityManager는 JPA에서 제공하는 interface로 Spring 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를 반환해서 쿼리를 필요할 때 보낸다.
'IT > Spring boot' 카테고리의 다른 글
[Spring boot] Ck Editor5 파일 업로드 최적화 과정 (0) | 2024.08.12 |
---|---|
[Spring boot] Ck Editor5 파일 업로드 구현 (0) | 2024.08.12 |
[Spring boot] Persistent Framework & JPA의 등장 (0) | 2024.08.11 |
[Spring boot] POJO (Plain Old Java Object) (0) | 2024.08.10 |
[Spring boot] Spring Singleton Bean (0) | 2024.08.09 |