자바 ORM 표준 JPA 프로그래밍 기본편 - 3. 영속성 관리 - 내부 동작 방식
Updated:
김영한님의 인프런 강의 - 자바 ORM 표준 JPA 프로그래밍 - 기본편
위 강의를 정리한 내용입니다.
I. 영속성 컨텍스트
- JPA에서 가장 중요한 2가지
- 객체와 관계형 데이터베이스 매핑하기
- 영속성 컨텍스트
개요
- 엔티티를 영구 저장하는 환경
- EntityManager.persist(entity);
- 현재 환경에서는 EM : 영속성 컨텍스트 = 1 : 1
- 스프링에서는 EM : 영속성 컨텍스트 = N : 1
엔티티의 생명주기
비영속
- 객체를 생성만 한 상태.
- 아직 JPA와는 전혀 관계가 없다.
영속
- 생성한 객체를
EntityManager
에persist
한 상태. EntityManager
내부의 영속성컨텍스트에 의해 관리된다.- 영속되어도 아직 쿼리가 날라가지는 않는다. 즉 디비에 저장되지 않는다.
준영속, 삭제
- 영속상태의 객체를 다시 제외시킨다.
왜 영속성 컨텍스트가 필요한가?
1차 캐시
em.find
실시할 때 데이터베이스보다 먼저 1차캐시를 조회한다.- 만약 1차캐시에 없다면 DB를 조회하고 1차캐시에 저장한 후 1차캐시에서 다시 반환한다.
- 수많은
EntityManager
가 생성되고 사라지기 때문에 1차캐시로 사실상 큰 이점을 가지진 않는다.
영속 엔티티의 동일성 보장
- 마치 컬렉션이서 꺼내는 것 처럼 같은
Entity
를 꺼내면 둘의 동일성을 보장해준다. (==
비교시true
를 반환한다)
엔티티 등록 - 트랜잭션을 지원하는 쓰기 지연
- 트랜잭션을 시작하고나서 커밋하기 전까지 모든 INSERT문을 보내지 않고 쌓아둔다.
엔티티 수정 - 변경 감지
- DB에서 꺼내온
Entity
를 수정하면 다시persist
하지 않아도 알아서 변경을 감지하고 DB에 적용한다. - 1차캐시 안에는
@Id
와Entity
외에도 최초로 1차캐시에 들어온 상태를 저장하는스냅샷
이 있다. - 만약 스냅샷과 Entity가 다르다면 쓰기 지연 SQL 저장소에
UPDATE
쿼리를 올려놓는다.
II. 플러시
- 영속성 컨텍스트의 변경내용을 데이터베이스에 반영
플러시 발생
- 변경 감지
- 수정된 엔티티를 쓰기 지연 SQL 저장소에 등록
- 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송
- 1차캐시는 지워지지 않고 유지된다.
플러시하는 방법
- em.flush() - 직접 호출
- 트랜잭션 커밋 - 플러시 자동 호출
- JPQL 쿼리 실행 - 플러시 자동 호출
- JPQL은 즉시 날라가는데, 필요한 데이터가 쓰기 지연 SQL 저장소에 있으면 조회가 불가능하므로 JPQL쿼리 실행시 flush된다.
- 플러시 옵션
em.setFlushMode(FlushModeType.AUTO)
: 커밋이나 쿼리를 실행할 때 플러시(기본값)em.setFlushMode(FlushModeType.COMMIT)
: 커밋할 때만 플러시
III. 준영속 상태
- 영속 -> 준영속
- 영속 상태였던 엔티티가 영속성 컨텍스트에서 분리
- 영속성 컨텍스트가 제공하는 기능을 사용 못함
준영속 상태로 만드는 방법
em.detach(entity)
: 특정 엔티티 지우기em.clear()
: 영속성 컨텍스트 통째로 지우기em.close()
: 영속성 컨텍스트를 종료
Leave a comment