프로그래밍/Java
[JPA] 영속성 관리
southouse
2021. 8. 25. 11:13
728x90
Entity 란?
- DB 테이블에 매핑되는 자바 클래스
영속성 컨텍스트 (Persistence Context)
Entity
를 영구히 저장하는 환경- Entity Manager → Persistence Context → Database 순으로 접근
- 1차 캐시
- 만약,
find()
메소드를 호출했을 때, 영속성 컨텍스트의 1차 캐시에서 찾고 없으면 데이터베이스에서 조회한다. - 캐시로 성능 상의 이점을 누릴 수 있음.
- 만약,
- 동일성 보장
- 영속성 컨텍스트에서 관리하는 엔티티 객체는 동일성을 보장해준다.
- 트랜잭션을 지원하는 쓰기 지연
- 변경 감지
- 지연 로딩
- 1차 캐시
Entity Lifecycle
- 비영속
- 객체 생성한 직후, 영속성 컨텍스트와는 관계가 전혀 없음.
- 영속
persist()
나find()
메소드를 통해 엔티티를 저장하거나 조회하면 영속 상태 (=엔티티가 영속성 컨텍스트에 저장되고, 엔티티 매니저에 의해 관리된다)
- 준영속
detach()
메소드로 준영속 상태로 전환 가능- 전환 시에 1차 캐시, 쓰기지연 저장소에 저장된 정보들이 모두 삭제 됨
행위 (Behavior)
- 조회 →
find()
- 영속성 컨텍스트를 거쳐서 조회한다.
- 등록 →
persist()
- 메소드를 실행하면, 쓰기지연 SQL 저장소에 insert쿼리를 등록하고, 영속성 컨텍스트에 저장한다.
- 쓰기지연을 수행하는 이유는, 네트워크 통신 횟수를 줄여 이득을 취하기 위함.
- 마지막 flush 동작 이후에 데이터베이스로 쿼리를 보낸다.
- flush란, 트랜잭션이 끝나는 시점에 정보들을 종합하여 최종 SQL을 날리는 행위 또는 명령
- 메소드를 실행하면, 쓰기지연 SQL 저장소에 insert쿼리를 등록하고, 영속성 컨텍스트에 저장한다.
- 수정
- JPA에 변경감지라는 기능이 있어 딱히 메소드가 존재하지 않는다.
- 엔티티가 영속상태에 들어가면, 스냅샷을 찍어두어 flush가 일어날 때 영속성 컨텍스트에 저장된 엔티티의 속성 값과 엔티티 스냅샷의 속성 값을 비교하여 변경된 부분을 감지해서 변경한다. → dirty check가 따로 필요 없음.
- 실제 update 이벤트가 발생하면 전체 속성에 대한 업데이트를 실행하는 쿼리가 생성된다.
@DynamicUpdate
라는 어노테이션으로 수정된 데이터에 대해서만 update를 할 수 있다.
- 삭제 →
remove()
- 데이터를 준영속 상태로 바꾸는
detach()
메소드와 데이터베이스에서 데이터를 삭제하는 delete 이벤트가 합쳐진 것
- 데이터를 준영속 상태로 바꾸는
- 병합 →
merge()
- 데이터를 준영속 상태에서 영속 상태로 만드는 행위
- 해당 엔티티가 영속화될 수 있는지(실재 존재하는지) 체크하기 위해 조회 이벤트를 날리게 된다.
- JPA 명세에서는 해당 엔티티를 찾을 수 없을 경우
IllegalArgumentException
이 발생하게 됨- hibernete에서는 그냥 새로 저장해주고, 영속성 컨텍스트에 등록하여 리턴
- 반영 →
flush()
- 영속성 컨텍스트의 변경 내용을 데이터베이스에 최종적으로 반영하는 행위 (commit과는 다름)
- 발생시키는 방법
- 직접 호출 →
em.flush()
- 트랜잭션 commit시에 자동 호출
- JPQL 실행 시 자동 호출
- 직접 호출 →
- flush 모드 →
javax.persistence.FlushModeType
FlushModeType.AUTO
- commit이나 쿼리를 실행할 때 flushFlushModeType.COMMIT
- commit할 때만 flus
Reference
300x250