객체와 관계형 데이터베이스 매핑하기(ORM)
영속성 컨텍스트

사용자 요청을 받으면 엔티티 매니저 팩토리에서 엔티티 매니저를 생성한다.
이후 커넥션 풀에있는 쓰레드를 사용해서 DB와 통신한다.
"데이터를 영구 저장하는 환경"
EntityManager.persist(entity);
논리적인 개념으로 눈에 보이지 않는다.
엔티티 매니저를 통해서 영속성 컨텍스트에 접근한다.
엔티티 매니저와 영속성 컨텍스트가 N:1의 관계이다.
비영속 : 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
영속 : 영속성 컨텍스트에 관리되는 상태. em.persist(member);
준영속 : 영속성 컨텍스트에 저장되었다가 분리된 상태 em.detach(member);
삭제 : 삭제된 상태 em.remove(member);
1차 캐시는 키-값 쌍의 형태를 가지고 있다고 생각하면 된다. Id-Entity의 관계이다.
영속성 컨텍스트는 어플리케이션과 DB 사이 중간에 있다고 볼 수 있는데, 영속성 컨텍스트에 저장된 객체를 조회할때 DB에서 쿼리문을 날려서 조회하지 않고 영속성 컨텍스트에서 바로 조회한다. 이 부분에서 성능이 향상된다. 만약 영속성 컨텍스트에 없으면 DB에 쿼리를 날려서 조회 한 후 1차 캐시에 저장하고 반환한다.
영속성 컨텍스트에서 가져온 논리적으로 동일한 객체를 동일성 비교에 참이라고 반환한다.
데이터 변경시 변경하는 코드가 바로 쿼리문을 날리지 않고 마지막에 커밋할때 쿼리문을 한꺼번에 날린다. 커밋 전에는 영속성 컨텍스트 안의 쓰기 지연 SQL 저장소에 쿼리를 쌓아 놓는다.

em.update(member); 같은 코드 없이 member.setName("hi"); 같이 영속된 엔티티의 데이터를 수정하는 코드가 실행되면서 영속성 컨텍스트에 반영되는 것을 변경감지(더티체킹)이라고 한다. 마지막에 커밋될 때 실제 SQL 쿼리가 나가는데, 1차 캐시안의 엔티티와 스냅샷(영속 초기의 객체)을 비교해서 차이가 있으면 쓰기 지연 SQL 저장소에서 UPDATE SQL을 생성하고 DB에 쿼리를 날린다. 엔티티 삭제할때도 같은 메커니즘이다.
나중 글에 적을 예정
영속성 컨텍스트의 변경 내용을 데이터베이스에 반영하는 것이다.
변경 감지, 수정된 엔티티 쓰기 지연 SQL 저장소에 등록, 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송
em.flush() - 직접 호출
트랜잭션 커밋 - 플러시 자동 호출
JPQL 쿼리 실행 - 플러시 자동 호출
영속성 컨텍스트를 비우지 않는다
영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화한다
트랜잭션이라는 작업 단위가 중요함 -> 커밋 직전에만 동기화 하면 된다.
영속 상태의 엔티티가 영속성 컨텍스트에서 분리된 상태이다.
영속성 컨텍스트가 제공하는 기능을 사용하지 못한다.
em.detach(entity)
em.clear()
em.close()
출처 : 인프런 자바 ORM 표준 JPA 프로그래밍 - 기본편