1. EntityManagerFactory & EntityManager
- DB를 하나만 사용한다면 Application은 일반적으로 하나의 EntityManagerFactory를 생성한다.
- 이제, 필요할 때마다 EntityManager를 생성하면 된다.
💡 EntityManagerFactory
- 만드는 비용이 상당히 큼 -> Application 전체에서 공유하고록 설계
- 여러 Thread가 동시 접근해도 안전 -> 서로 다른 Thread간 공유 가능
💡 EntityManager
- Factory에서 생성하는 비용이 거의 안듬
- 여러 Thread가 접근하면 동시성 문제 발생 -> 절대 공유 X
- DB연결이 실제로 필요한 시점(트랜잭션 시작 시점)까지 DB 커넥션을 얻지 않음!
-> 보통 Transaction 시작할 때 커넥션 획득

2. 영속성 컨텍스트 (persistence context)?
- 엔티티를 영구저장하는 환경
- 그 동안 사용했던
persist(Object o)는 단순 DB저장 ❌
-> 엔티티 매니저를 사용, 회원 엔티티를 영속성 컨텍스트에 저장 ⭕
3. 엔티티의 생명주기

3.1. 비영속 (new/transient)
- 영속성 컨텍스트와 전혀 관계가 없는 상태
- 객체 생성 후
persist() 호출 전 -> 순수한 객체상태

3.2. 영속 (managed)
- 영속성 컨텍스트에 저장된 상태
-> 영속성 컨텍스트에 의해 관리
- EntityManager를 통해 Entity를 영속성 컨텍스트에 저장

3.3. 준영속 (detached)
- 영속성 컨텍스트에 저장되었다가 분리된 상태
- 준영속으로 만드는 법
detach()로 분리
close()를 통해 닫기
clear()로 초기화
3.4. 삭제 (remove)
- DB 삭제가 예정된 상태 (
remove() 호출 후 트랜잭션 커밋 전 상태)
- 삭제하는 법
4. 영속성 컨텍스트의 특징
4.1. 식별자 필수!
- 영속성 컨텍스트는 식별자로 구분
- 영속 상태는 식별자가 무조건 있어야 함!
- 없다면 Error
4.2. Flush
4.3 장점
4.3.1. 1차 캐시
- 영속성 컨테스트가 가지고 있는 내부 캐시 (Key:Value 형식)
- 영속 상태의 엔티티는 모두 이곳에 저장

- 1차 캐시의 키는 Id
-> 즉,식별자임 & 식별자 값은 DB PK와 Mapping 되있음
-> 저장 & 조회의 모든 기준은 DB의 PK임!
4.3.2. 동일성 보장
4.3.3. Transaction을 지원하는 쓰기 지연
4.3.4. 변경 감지 (Dirty Checking)
4.3.5. 지연 로딩
5. CRUD로 알아보는 특징!
5.1. Read

- 일련의 과정
find() 호출
- 1차 캐시에서 식별자 값으로 Entity 탐색
- 있으면 해당 값 return
- 없다면 DB에서 조회해서 entity 생성
- 해당 entity를 1차 캐시에 저장 후 영속 상태의 entity 반환
Sample a =
entityManager.find(Sample.class, "1");
Sample b =
entityManager.find(Sample.class, "1");
System.out.println(a == b);
- 동일한 조건의
find()을 반복 호출해도 영속성 컨텍스트는 1차 캐시에 있는 같은 entityManager를 반환
-> 즉, return true
성능상 이점과 entity의 동일성을 보장
5.2. Create
- 엔티티 매니저는 Trasaction을 commit하기 직전까지 DB에 entity를 저장 ❌, 내부 쿼리 저장소에 SQL을 모아둠
- Transaction commit하며 쿼리를 DB에 보냄
-> 해당 과정이 Transaction을 지원하는 쓰기 지연


-
일련의 과정
persist()
- insert SQL 생성 & 1차 캐시에 저장
- app -> em :
commit()
- em -> DB : flush
- em -> DB : commit
-
ex)
begin();
save();
save();
save();
commit();
등록 쿼리를 트랜잭션 커밋 시 일괄 전송 → 성능 최적화 가능!
5.3 Update
- SQL을 통한 수정 작업의 문제점 (비즈니스 로직이 SQL에 의존!)
- 수정 쿼리가 많아짐
- 비즈니스 로직을 분석하기 위해 SQL을 주기적으로 확인해야 함
- JPA에서는 Entity를 조회 후 필드만 변경하면 자동으로 update됨.
-> Dirty Checking을 통해 가능!

- 스냅샷
- Entity를 영속성 컨텍스트에 보관 시, 최초 상태를 복사해서 저장.
- flush 시점에 스냅샷과 현재 Entity 상태를 비교하여 변경사항을 감지함.
- 오직, 영속성 컨텍스트가 관리하는 영속 상태의 엔티티만 적용
- JPA 기본 전략으로 변경 사항이 있는 엔티티의 모든 필드를 Update
- Hibernate의 @DynamicUpdate를 사용하면 수정된 필드만 업데이트 가능!
5.4 Delete
- 일련의 과정
remove()
- delete SQL 생성
- app -> em :
commit()
- em -> DB : flush
- em -> DB : commit
6. 준영속
- 영속성 컨텍스트가 관리하는 영속상태의 Entity가 영속성 컨텍스트에서 분리된 것
-> 준영속 Entity는 영속성 컨테스트가 제공하는 기능 사용 ❌
6.1. 영속 -> 준영속
6.1.1. detach()
-
특정 Entity를 준영속 상태로 만드는 Method
-
영속성 컨텍스트에서 분리되면 변경 감지, 쓰기 지연, 1차 캐시 등 기능이 모두 비활성화됨
6.1.2. clear()
- 영속성 컨텍스트를 초기화
-> void 상태로 만듬, 모든 Entity를 준영속으로 만듬
6.1.3. close()
- 영속성 컨텍스트 종료
-> 완전 종료, 모든 Entity를 준영속으로 만듬
6.2. 준영속 특징
- 거의 비영속과 가까움
- 식별자를 가짐
- 지연 로딩 ❌
6.3 준영속 -> 영속