JPA를 공부중이다. TypeORM과 비슷한 맥락을 가져가서 거부감이 없다. 하긴 결국 객체와 테이블을 매핑한다는 점은 같으니까. 언제나 그렇듯 SQL을 몰라서 ORM을 쓴다는 개념이 아니라 양쪽 모두를 효율적으로 관리한다는 관점에서 접근하자.
영속성 컨텍스트란 엔티티를 영구 저장하는 환경.
엔티티는 영속성 컨텍스트 내에서 보관하고 관리된다. 이때, 엔티티를 식별자 값(@Id로 기본키로 매핑한 값)으로 구분하니 영속상태는 식별자 값이 반드시 있어야 한다.
생명주기
'영속 상태'라는 것은 영속성 컨텍스트에 의해 관리 된다는 뜻이다.
엔티티에는 4가지 상태가 존재한다.
1. 비영속
2. 영속
3. 준영속(영속성 컨텍스트에 저장되었다가 분리된 상태)
4. 삭제
플러시
영속성 컨텍스트에 새로된 저장된 엔티티를 데이터베이스에 반영하는 것을 플러시(flush)라 한다.
플러시라는 이름으로 인해 영속성 컨텍스트에 보관된 엔티티를 지운다고 생각하면 안됨. 그저 동기화
ex. find 메소드 호출 시,
1. 먼저 영속성 컨텍스트 내의 1차 캐시에서 엔티티를 찾고,
2. 만약 찾는 엔티티가 1차 캐시에 없으면 데이터베이스에서 조회한다.
3. 데이터베이스에서 조회 후 1차 캐시에 저장한 후에 영속 상태의 엔티티를 반환
쓰기 지연
트랜잭션을 바로 디비에 반영하지 않고, 내부 쿼리 저장소에 모아둔다. 그리고 트랜잭션을 커밋할때 한번에 디비에 보낸다. 이를 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)이라 한다.
update()는 없다: 변경 감지
변경 감지(dirty checking): 엔티티의 변경사항을 데이터베이스에 자동으로 반영하는 기능.
엔티티를 영속성 컨텍스트에 보관 시, 최초 상태 복사본을 따놓음. 이것을 스냅샷이라고 함. 그리곤 플러시 시점에 스냅샷과 엔티티를 비교해서 변경된 엔티티를 찾음.
FYI
동일성: 실제 인스턴스가 같다. (same)
동등성: 인스턴스가 지닌 '값'이 같다. (equal)