JPA 영속성 컨텍스트, 엔티티 생명주기, 변경 감지

2023. 12. 11. 14:40북리뷰/자바 ORM 표준 JPA 프로그래밍

728x90

영속성 컨텍스트(persistence context)

쉽게 말하면 엔티티를 영구 저장하는 환경이다.

즉, 엔티티 메니저로 엔티티를 저장하거나 조회하면 엔티티메니저는 영속성 컨텍스트에 엔티티를 보관하고 관리한다.

영속성 컨텍스트는 엔티티 메니저 당 하나씩 할당한다

 

 

엔티티의 생명주기

엔티티는 4가지 상태가 존재한다.

 - 비영속 : 영속성 컨텍스트와 전혀 관계가 없는 상태

순수한 객체 상태이며, 아직 저장되지 않음. DB와 전혀 관련 없는 객체

- 영속 : 영속성 컨텍스트에 저장된 상태

- 준영속 : 영속성 컨텍스트에 저장되었다가 분리된 상태 

영속성 컨텍스트가 관리하지 않으므로 거의 비영속 상태에 가깝고, 그렇기에 지연 로딩을 할 수 없다.

하지만, 식별자 값을 가지고 있다는 특징이 있다.

- 삭제 : 삭제된 상태, 실제로 DB에서 삭제한 상태.

 

영속성 컨텍스트는 엔티티를 식별자 값으로 구분한다.

즉, 영속 상태는 식별자 값이 반드시 있어야 한다.

영속성 컨텍스트에 있다가. 트랜젝션을 커밋하는  순간 DB에 반영하는데. 이것을 플러시(flush) 라고 한다.

물론, entity manager에서 flush 함수를 호출해도 DB에 반영한다.

 

영속성 컨텍스트 내부에는 캐시를 가지고 있는데, 이것을 1차 캐시라고 한다.

entity manager에서 find를 호출하면 먼저 1차 캐시에서 엔티티를 찾고, 만약 엔티티가 1차 캐시에 없으면 DB에서 조회한다.

 

 

find를 여러번 호출해도 연속성 컨텍스트는 1차케시에 있는 같은 엔티티 인스턴스를 반환한다.

이를 통해 영속성 컨텍스트는 성능상 이점과 엔티티 동일성을 보장한다.

 

변경 감지

 

JPA에서는 객체 수정 후 별도 update 쿼리를 날리지 않아도, 변경을 감지하여 자동으로 DB에 반영한다.

어떻게 감지할 수 있을까?

 

JPA에서는 엔티티를 영속성 컨텍스트에서 보관할 때, 최초 상태를 복사하여 저장해두는데 이것을 스냅샷이라고 한다.

JPA에서는 플러시 시점에 스냅샷과 엔티티를 비교해서 변경된 엔티티를 찾는다.

즉, 변경 감지는 영속성 컨텍스트가 관리하는 영속 상태의 엔티티에만 적용한다.

 

 

참고로 jpa에서 update 쿼리 작성 시 엔티티의 모든 필드를 업데이트한다.

 

플러시(flush)

영속성 컨텍스트의 변경 내용은 DB에 반영한다.

변경 감지가 동작해서 영속성 컨텍스트에 있는 모든 엔티티와 스냅샷을 비교해서 수정 쿼리를 만들어 쓰기 지연 SQL 저장소에 등록하고,

쓰기 지연 SQL 저장소에서 쿼리를 DB에 전송한다.

em.flush()를 직접 호출하거나, 트랜젝션 커밋 시, JPQL 쿼리 실행시 플러시가 자동으로 호출된다.

 

728x90

'북리뷰 > 자바 ORM 표준 JPA 프로그래밍' 카테고리의 다른 글

JPA Entity Manager  (0) 2023.12.11