엔티티를 영구 저장하는 환경
엔티티 메니저로 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리함
엔티티 매니저를 하나 생성할 때 영속성 컨텍스트 하나가 생성됨
쉽게 생각해서 하나의 엔티티 매니저 - 영속성 컨텍스트 가 매핑되어 있다고 생각하면 됨
영속성 컨텍스트는 엔티티를 식별자 값(Id) 으로 구분한다. 따라서 영속상태는 식별자 값이 반드시 있어야 될 수 있다.
JPA는 보통 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 데이터베이스에 반영한다.
개발자 입장에서는 엔티티 매니저 = 엔티티를 저장하는 가상의 데이터베이스로 생각하면 된다.
말 그대로 엔티티매니저는 엔티티 관리 객체이다.
위에서 언급했듯이 하나의 엔티티 매니저는 하나의 영속성 컨텍스트와 매핑되어 있다.
엔티티 매니저를 이용하여 CRUD 시 각 엔티티 매니저와 매핑된 영속성 컨텍스트에서 엔티티가 CRUD된다.
- 엔티티 매니저를 통해 영속성 컨텍스트에 저장된 엔티티
- em.find()나 JPQL을 사용해서 조회된 엔티티
영속 상태의 엔티티는 모두 이곳에 저장됨
em.find()를 호출하면 먼저 1차 캐시에서 엔티티를 찾고 만약 찾는 엔티티가 1차 캐시에 없으면 데이터베이스에서 조회한다.
이에 따라 성능상 이점을 누릴 수 있다.
[주의🎇] 만약에 개발하다가 쿼리가 나가야 하는 시점에 안나간게 있다면 단순 코드 오류일 수도 있지만 1차 캐시에서 조회하느라 쿼리가 나가지 않은 것일 수도 있다. 이 점을 늘 염두에 두고 개발하자!
영속성 컨텍스트는 1차 캐시에 있는 같은 엔티티 인스턴스를 반환한다. 이때 인스턴스의 동일은 단순히 내용이 같은 것이 아닌, 정말 == 의 관계에 있음을 의미한다.
엔티티 매니저는 트랜잭션을 커밋하기 직전까지 데이터베이스에 엔티티를 저장하지 않고 내부 쿼리 저장소에 INSERT SQL을 차곡차곡 모아둔다. 이를 쓰기 지연이라고 한다.
JPA는 엔티티를 영속성 컨텍스트에 보관할 때 최초 상태를 복사해서 저장해두는데 이것을 스냅샷이라고 한다. 그리고 플러시 시점에 스냅샷과 엔티티를 비교해서 변경된 엔티티를 찾는다.