JPA 이해하기 위해 영속성 컨텍스트를 이해해야한다.
영속성 컨텍스트란?
영속성 컨텍스트는 엔티티를 영구 저장하는 환경 이라는 뜻이다.
웹에서 고객 요청이 올 때마다 엔티티 매니저가 생성이 되는데, 이 엔티티 매니저를 통해서 영속성 컨텍스트에 접근을 한다. (엔티티 매니저는 트랜젝션 단위로 만들어진다.)
entityManager.persist(member);
이런 식으로 엔티티 매니저로 엔티티를 저장하거나(persist) 조회(find)하면 영속성 컨텍스트에 엔티티를 보관하고 관리한다.
영속성 컨텍스트가 엔티티를 관리하면 좋은 점
1 1차 캐시
영속성 컨택스트는 내부에 1차캐쉬를 갖고 있다.
엔티티를 식별자 값(@Id 맵핑)으로 구분한다. Map (Key-value)로 관리하는데 이때 key 값이 @Id 값이고 value가 엔티티이다.
- 엔티티 매니저가 find(member1) 메서드를 호출하게 되면, 1차 캐시부터 접근을 하는데 이미 member1이 있다면, JPA는 1차 캐시부터 조회한다.
- find(member2) 했을 때, 1차 캐시에 member2가 없다면 JPA는 DB에 접근해 조회한 다음 1차 캐시에 저장하고 member2를 반환한다.
캐시를 사용하면 DB에 접근하지 않아도 되므로 성능상의 이점을 누릴 수 있습니다.
(1차 캐시는 한 트랜잭션 안에만 동작 있기 때문에 큰 성능의 이점을 주지 못한다. )
2. 동일성 보장
1차 캐시에 있는 엔티티를 조회하므로 동일한 객체를 반환합니다.
3. 트랙잭션을 지원하는 쓰기 지연
persist() 메서드를 호출하면 객체는 1차캐쉬에 저장되고 jpa 엔티티를 분석해서 insert쿼리를 만들어 쓰기 지연 sql 저장소에 저장한다.
flush가 되면서 commit()메서드 호출하는 시점에 영속성에 있는 쿼리가 날라가 DB에 저장된다.
이를 트랜잭션을 지원하는 쓰기지연이라 한다.
4. 변경 감지 ( dirty checking )
변경할때 find() 하고 persist() 해서 update() 해야할 거 같은데 그럴 필요가 없다.
변경감지를 하기 때문이다.
커밋하면 flush()가 호출되고 엔티티와 스냅샷을 비교한다.
엔티티가 1차 캐시에 최초로 저장될 때, 그 상태를 복사해서 같이 저장해두는데 그것을 스냅샷이라고 한다.
비교해서 바뀐 부분보고 쓰기 지연 sql 저장소에 update쿼리 만들어서 db에 반영해서 영속성 컨텍스트에도 변경된다.
그래서 따로 update해줄려고 코드를 짤 필요가 없다. jpa가 자동으로 다 해주기때문에..
플러시 (flush)란?
영속성 컨텍스트 내용을 DB에 반영하는 것이다. 트랙젝션 commit()이 호출되면 자동으로 플러시가 생성된다.
- 변경 감지
- 수정된 엔티티 쓰지 지연 SQL 저장소에 등록
- 쓰지 지연 SQL 저장소의 쿼리를 DB에 전송
개발 중에, 쿼리 미리 보고싶거나 미리 날리고 싶으면 em.flush()를 사용하면 된다.
준영속 상태란?
영속 상태 엔티티가 영속성 컨테스트에서 분리되는 것을 말한다.
detach()메소드로 준영속상태로 전환시킨다.
위에 update를 쳐도 em.detach()나 em.clear()(영속성 초기화)를 해주면 조회쿼리만 나가고 업데이트 쿼리는 안 나간다.
참고
인프런 자바 ORM 표준 JPA프로그래밍 -기본편
'JPA' 카테고리의 다른 글
JDBC 이해 (작성중) (0) | 2023.08.24 |
---|