22.05.29
03. 영속성 관리
JPA 내부 구조
영속성 컨텍스트
엔티티를 영구 저장하는 논리적 환경. 일종의 1차 캐시.
key: @Id, value: Entity 객체 형태로 저장한다.
EntityManager.persist(entity) 메서드는 사실 데이터베이스에 저장하는 것이 아니라, 영속성 컨텍스트에 저장하는 것이다.

엔티티의 생명주기
• 비영속 (new/transient): 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태 (엔티티 생성)
• 영속 (managed): 영속성 컨텍스트에 관리되는 상태 (엔티티 persist)
• 준영속 (detached): 영속성 컨텍스트에 저장되었다가 분리된 상태
• 삭제 (removed): 데이터베이스에서 삭제된 상태
영속성 컨텍스트의 이점
• 1차 캐시: em.find(id) -> 영.컨에 있으면 그대로 반환, 없으면 DB에서 찾아 영.컨에 저장 후 반환
• 동일성(identity) 보장
• 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)
• 변경 감지(Dirty Checking)
• 지연 로딩(Lazy Loading)
*영속성 컨텍스트는 트랜젝션 단위로 생성되기 때문에 한 고객이 들어와서 나가는 찰나의 순간에만 유효하다. 따라서 1차 캐시 역할로 얻는 이점은 미미하다.
*데이터베이스 탐색: sql 쿼리 있음 / 영속성 컨텍스트 탐색: sql 쿼리 없음
*Entity 클래스는 파라미터가 없는 생성자를 반드시 필요로 한다.
트랜잭션을 지원하는 쓰기 지연


*Hibernate Batch (대량의 데이터 작업을 한 번에 처리)
<property name="hibernate.jdbc.batch_size" value="10"/>
10개의 쿼리 구문을 1개의 쿼리 구문으로 처리한다.
여러 개의 구문을 여러 번 network 를 통해 보내는 것이 아니라 합쳐서 1개로 보내기에 성능 개선을 할 수 있다.
jpa 의 경우 트랜잭션이 commit 되는 순간 한꺼번에 flush 한다.
Entity Key 생성을 GenerationType.IDENTITY 로 하면 batch 옵션이 동작하지 않는다. IDENTITY 옵션은 쿼리가 수행된 이후에 값을 얻을 수 있기에 batch insert 옵션은 사용할 수 없다.
변경 감지

영속성 컨텍스트는 엔티티를 1차 캐시에 보관할 때 최초 상태를 복사해서 따로 저장해둔다. 이를 스냅샷이라고 한다.
트랜잭션이 커밋되는 시점(flush() 호출)에 엔티티와 스냅샷을 비교하여 변경 사항이 있다면 update 쿼리를 생성하여 쓰기 지연 SQL 저장소에 저장한다.