JPA는 보통 트랜잭션 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 데이터베이스에 반영하는데 이를 플러시(flush)라 한다.
영속성 컨텍스트가 엔티티 관리할 경우의 장점
1차 캐시
동일성 보장
트랜잭션을 지원하는 쓰기 지연
변경 감지
지연 로딩
3. 엔티티 조회
영속성 컨텍스트는 내부에 캐시를 가지고 있는데 이것을 1차 캐시라 한다.
영속상태의 엔티티는 모두 이곳에 저장된다. 즉, 영속성 컨텍스트 내부에 Map이 하나 있는데 키는 @Id로 매핑한 식별자고 값은 엔티티 인스턴스이다.
em.find() 호출하면 먼저 1차 캐시에서 엔티티를 찾고 만약 1차 캐시에 없으면 데이터베이스에서 조회한다
4. 엔티티 등록
엔티티 매니저는 트랜잭션을 커밋하기 직전까지 데이터베이스에 엔티티를 저장하지 않고 내부 쿼리 저장소에 insert sql을 차곡 모아둔다. 그리고 트랜잭션을 커밋할 때 모아둔 쿼리를 데이터베이스에 보내는데 이것을 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)이라 한다
트랜잭션을 커밋하면 엔티티 매니저는 우선 영속성 컨텍스트를 플러시한다.
플러시는 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화하는 작업인데 이때, 등록, 수정, 삭제한 엔티티를 데이터베이스에 반영한다.
이렇게 변경 내용을 데이터베이스에 동기화 한 후에 실제 데이터베이스 트랜잭션을 커밋한다.
5. 엔티티 수정
SQL을 사용하면 데이터를 수정할 때마다 쿼리가 생성이 된다. 이런 방식의 문제는 수정 쿼리가 많아지고 비즈니스 로직을 분석하기 위해 SQL을 계속 확인해야 된다. 즉, SQL에 의존적이게 된다.
JPA로 엔티티를 수정할 때는 단순희 엔티티를 조회해서 데이터만 변경하면 된다. 엔티티의 데이터만 변경했는데도 데이터베이스에 반영되는 이유는 엔티티의 변경사항을 데이터베이스에 자동으로 반영하는 변경감지(dirty checking) 기능 때문이다.
JPA는 엔티티를 영속성 컨텍스트에 보관할 때, 최초 상태를 복사해서 저장해두는데 이것을 스냅샷이라 한다. 그리고 플러시 시점에 스냅샷과 엔티티를 비교해서 변경된 엔티티를 찾는다
JPA의 기본전략은 엔티티의 모든 필드를 업데이트 한다.
수정 시 모든 필드를 사용하면 수정쿼리가 항상 같다. 따라서 애플리케이션 로딩 시점에 수정 쿼리를 미리 생성해두고 재사용할 수 있다.
데이터베이스에 동일한 쿼리를 보내면 데이터베이 스는 이전에 한 번 파싱된 쿼리를 재사용할 수 있다.
6. 엔티티 삭제
em.remove()에 삭제 대상 엔티티를 넘겨주면 엔티티를 삭제한다.
엔티티를 즉시 삭제하는 것이 아니라 엔티티 등록과 비슷하게 삭제 쿼리를 쓰기 지연 SQL 저장소에 등록한다.