JPA에서 가장 중요한 2가지
- Mapping : 객체와 관계형 데이터를 각 어떻게 설계하여 매핑할 것인가. (설계 관련. 정적인 것)
- 영속성 컨텍스트
영속성 컨텍스트 : Entity를 영구 저장하는 환경
- Entitymanager.persist(entity): DB에 저장하는 메소드가 아닌, 영속성 컨텍스트에 저장하는 메소드!
- 논리적인 개념. 가시적이지 않음.
- 엔티티 매니저를 통해 영속성 컨텍스트에 접근
- 엔티티 생명주기
영속성 컨텍스트의 이점
- 1차 캐시 ( 하나의 트랜젝션에서의 캐시)
- 영속성 컨텍스트 내부의 캐시
- cf) 2차 캐시 : Application 전체에서 공유하는 캐시
- 동일성(identity) 보장 : 1차 캐시로 반복 가능한 읽기 (repeatable read) 등급의 트랜젝션 격리 수준을 데이터 베이스가 아닌 애플리케이션 차원에서 제공
- 동일성과 동등성
- 동일성 (identity) : 실제 인스턴스가 같다. 따라서 참조 값을 비교하는 == 비교의 값이 같다.
- 동등성 (equality) : 실제 인스턴스는 다를 수 있지만 인스턴스가 가지고 있는 값이 같다. 자바에서 동등성 비교는 equals() 메소드를 구현해야 한다.
- 동일성과 동등성
- 트랜젝션을 지원하는 쓰기 지연 ( transactional write-behind)
- transaction commit하는 순간에 SQL 전송
- 영속 컨텍스트 (EntityManeger)에는 1차 캐시 이외의 쓰기 지연 SQL 저장소가 존재.
- insert 작업 flow
- 1차 캐시와 쓰기 지연 저장소에 저장됨 (DB 전송 X) → 2. flush (DB 전송) → 3. commit
- update 작업 flow
- 변경된 entity가 persist → 2. 엔티티 정보 변경 감지 (dirty check) : 엔티티와 스냅샷을 비교하여 쓰기 지연 SQL 저장소에 쿼리 저장 → 3. UPDATE flush → 4. commit
- 변경 감지 (Dirty Checking)
- 지연 로딩 (Lazy Loading)
플러시 : 영속성 컨텍스트의 변경내용을 데이터베이스에 반영
- Application과 DB의 데이터를 맞추는 작업 (동기화)
- 플러시 작동해도 1차캐시는 지워지지 않음
- 플러시 발생하면 일어나는 일
- 변경 감지(dirty checking)
- 수정된 엔티티를 쓰기 지연 SQL 저장소에 등록
- 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송
- !!플러시가 발생한다고 쿼리를 DB에 반영(commit) 아니라, transaction commit에 쌓아둔 쿼리가 DB에 전송되는 것
- 영속성 컨텍스트를 플러시하는 방법
- em.flush() → 직접 호출
- 트랜젝션 커밋 → 플러시 자동 호출
- JPQL 쿼리 실행 → 플러시 자동 호출
- JPQL 쿼리 실행 시 플러시가 자동으로 호출되는 이유 : 영속성 컨텍스트에 저장된 이전 데이터/쿼리가 DB에 저장되지 않은 상태에서 JPQL의 쿼리문으로 DB데이터 조회 결과의 차이가 생길 수 있기 때문에 JPQL 쿼리 발생 이전에 flush 해야 함!
- 플러시 모드 옵션
- FlushModeType.AUTO : 커밋이나 쿼리를 실행할 때 플러시 (기본값)
- FlushModeType.COMMIT : 커밋할 때만 플러시 ( 굳이 옵션 변경하지 않는 것이 좋음)
- 플러시 특징
- 영속성 컨텍스트를 비우지 않음
- 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화
- 트랜잭션이라는 작업 단위가 중요 → 커밋 직전에만 동기화하면 됨
준영속 상태
- 영속 → 준영속
- 영속 상태의 엔티티가 영속성 컨텍스트에서 분리된 상태 (detached)
- 영속성 컨텍스트가 제공하는 기능을 사용하지 못함
- 준영속 상태로 만드는 방법
- em.detach(entity) : 특정 엔티티만 준영속 상태로 전환. 1차캐시 제거, 쓰기 지연 SQL 저장소의 관련 SQL 제거
- em.clear() : 영속성 컨텍스트를 완전히 초기화 (1차 캐시 등도 모두 초기화됨)
- em.close() : 영속성 컨텍스트를 종료 (데이터 변경 등의 관리가 전혀 안되는 상태)
- 직접 쓸 일은 거의 없음
- 준영속 상태의 특징
- 거의 비영속 상태에 가깝다. : 영속성 컨텍스트에서 관리하지 않기에 1차 캐시, 쓰기 지연, 변경 감지, 지연 로딩을 포함한 영속성 컨텍스트가 제고하는 어떠한 기능도 동작하지 않는다.
- 식별자 값을 가지고 있다. : 비영속 상태는 식별자 값이 없을 수도 있지만, 준영속 상태는 이미 영속 상태였으므로 반드시 식별자 값을 가지고 있다.
- 지연 로딩 불가
- 병합 merge(Entity) : 준영속 상태의 엔티티를 다시 영속 상태로 변경
- 준영속 상태의 엔티티를 받아서, 그 정보로 새로운 영속 상태의 엔티티 반환
- 준영속 / 비영속 두 상태에서 쓰임
출처 : 자바 ORM 표준 JPA 프로그래밍-기본편 (김영한), 자바 ORM 표준 JPA 프로그래밍(김영한 저)
'Programming > Database & Query' 카테고리의 다른 글
[JPA] 자바 ORM 표준 JPA 프로그래밍 : 다양한 연관관계 매핑 (0) | 2022.02.10 |
---|---|
[JPA] 자바 ORM 표준 JPA 프로그래밍 : 연관관계 매핑 기초 (0) | 2022.01.31 |
[JPA] GenerationType.Sequence 설정시 next value 두 번 호출하는 이유 (0) | 2022.01.25 |
[JPA] 자바 ORM 표준 JPA 프로그래밍 : 엔티티 매핑 (0) | 2022.01.20 |
[JPA] 자바 ORM 표준 JPA 프로그래밍 : JPA란, JPA 시작하기 (0) | 2022.01.16 |