Entity를 영구 저장하는 환경
Entity를 관리하기 위한 개념
JPA는 Entity Manager를 통해 Entity가 영속성 컨텍스트에 포함되어 있는지, 아닌지에 따라 데이터베이스에 변경사항을 저장하여 영속성을 부여할지, 말지를 결정
Entity Manager가 생성되어, 트랜잭션을 시작할 때, 영속성 컨텍스트 또한 만들어진다.
데이터를 Application 내에 변수로 저장하면, Application을 종료할 경우 데이터가 메모리에서 삭제됨 ※영속성이 없다. 영속성이 부여되지 않았다.
하지만 데이터베이스에 데이터를 저장하면, Application을 종료하더라도 데이터가 그대로 남아있음 ※영속성이 있다. 영속성이 부여됐다.
JPA는 Entity가 Transient(New), Managed, Detached, Removed 등의 상태에 있는지 추적
Entity의 상태를 통해 트랜잭션 종료시 DB에 최종적으로 어떤 쿼리를 날릴지를 결정
비영속(Transient): 아직 영속성 컨텍스트에 포함되지 않은 새로운 Entity 상태
영속(Managed): 영속성 컨텍스트에 저장된 상태
준영속(Detached): 영속성 컨텍스트에 저장되었다가 분리된 상태
삭제(Removed): 삭제된 상태

엔티티를 식별자 값으로 구분한다.
@Id 어노테이션을 사용하여, 테이블의 PK와 매핑한 값
영속 상태는 반드시! 식별자 값이 있어야 한다.
영속성 컨텍스트에 엔티티를 저장하고, 트랜잭션을 커밋하는 순간 데이터베이스에 저장된다.
플러시(Flush) = 엔티티를 데이터베이스에 반영한다
1차 캐시를 확인 후, 있다면 1차 캐시에서 가져온다.
1차 캐시를 확인 후, 없다면 DB에서 가져와서 1차 캐시에 저장 후 반환한다.단 transaction이 끝나면 영속 컨텍스트가 사라지기 때문에 1차 캐시도 사라지며, 쓰기 지연 SQL 저장소 또한 비워진다.
영속성 컨텍스트 내부에 가지고 있는 캐시
영속 상태(Managed)의 엔티티는 모두 이곳에 저장된다.
1차 캐시는 다음과 같은 Key-Value 형태의 구조를 가진다.

그렇다면 1차 캐시를 사용하는 이유가 뭘까?
네트워크를 통해 DB에 접근하는 시간 비용은 애플리케이션 서버에서 내부 메모리에 접근하는 비용보다 훨씬 비싸다.
따라서 조회한 데이터를 메모리에 캐시해서 DB접근횟수를 줄이는 것이 효율적이다.
플러시는 영속성 컨텍스트에 저장된 엔티티를 지우는 게 아니다!!!
영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화한다!!!
변경 내용: 1차 캐시에 새로운 멤버 등록됨, 기존 멤버 정보 수정, 1차 캐시에서 기존 멤버 삭제
트랜잭션을 커밋하면 엔티티 매니저 내부에서 flush()가 실행된다.
변경감지(dirty checking)가 동작해서 엔티티의 영속성 컨텍스트에 있는 모든 엔티티를 스냅샷과 비교해서 수정된 엔티티를 찾는다.
수정된 엔티티가 있으면 엔티티 매니저가 UPDATE SQL을 생성해서 쓰기 지연 SQL 저장소에 저장한다.
쓰기 지연 저장소의 SQL을 DB로 보낸다.
데이터베이스의 트랜잭션을 커밋한다.

위 이미지에는 flush가 2개가 있는데 2개의 flush는 같은 건가??
flush의 동작을 다시 한번 살펴보자.
변경 내용을 DB에 반영하는 것만 놓고 보면 4번이 flush라고 볼 수 있다.
그리고 그 과정에서 필요한 것들이 2, 3번이다.
4번의 flush는 flush()의 동작 중 하나다.
직접호출
엔티티 매니저의 flush 메소드를 직접 호출해서 영속성 컨텍스트를 강제로 플러시한다.
트랜잭션 커밋 시 플러시 자동 호출
트랜잭션을 커밋하기 전에 플러시를 호출해서 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영하지 않으면, 변경내용이 반영되지 않는다.
JPA는 이런 문제를 해결하기 위해서 트랜잭션을 커밋할 때 플러시를 자동으로 호출한다.
JPQL 쿼리 실행 시 플러시 자동 호출
JPQL이나 Criteria같은 객체지향 쿼리를 호출할 때도 플러시가 실행된다.
영속성 컨텍스트에게 해당 엔티티를 관리하지 말라는 명령어
1차 캐시부터, 쓰기 지연 SQL 저장소까지 해당 엔티티를 관리하기 위한 모든 정보가 제거된다.
영속성 컨텍스트가 지원하는 어떤 기능도 동작하지 않음
쓰기 지연 SQL의 SQL 또한 삭제되어서 데이터베이스에 저장되지도 않음


영속성 컨텍스트에게 기존에 영속성 컨텍스트에 들어있던 모든 엔티티를 관리하지 말라는 명령어
1차 캐시부터, 쓰기 지연 SQL 저장소까지 모든 정보가 제거된다.




비영속 상태(Transient)에 가깝다
식별자 값을 가지고 있다.
비영속 상태(Transient)는 식별자 값이 없을 수도 있다.
영속성 컨텍스트는 엔티티를 구별하기 위해서 식별자 값이 반드시 필요하지만, 영속성 컨텍스트에 들어가지 않은 엔티티는 없을 수도 있다.
준영속 상태는 영속성 컨텍스트에 한번 들어있었기 때문에 반드시 식별자 값을 가지고 있다.
지연 로딩이 불가능
준영속 상태의 엔티티를 받아서, 그 정보를 바탕으로 새로운 영속 상태의 엔티티를 반환
준영속 상태의 엔티티를 merge하면, 엔티티 매니저가 관리할 새로운 객체를 반환한다.