티스토리 뷰
영속성 컨텍스트란?
영속성 컨텍스트는 엔티티를 영구 저장하는 환경을 의미합니다.
엔티티에 대한 설명은 다음 포스팅을 참고해주세요.
엔티티의 정의와 생명주기(lifecycle)
엔티티의 정의 엔티티는 사전적 정의로 개체, 실재라는 뜻을 가집니다. JPA에서는 가볍게 데이터 모델링에서 사용되는 객체라고 생각하시면 됩니다. 코드를 가볍게 살펴봅시다. import lombok.AccessLe
kkoon9.tistory.com
영속성 컨텍스트를 쓰는 이유는 1차 캐시, 동일성 보장, 트랜잭션을 지원하는 쓰기 지연, 변경감지(Dirty checking), 지연로딩이 있습니다.
1차 캐시
영속성 컨텍스트 내부에 캐시를 1차 캐시라고 합니다.
영속 상태의 엔티티는 모두 1차 캐시에 저장이 됩니다.
Id 어노테이션을 매핑한 식별자를 Key로 가지는 Map이 있다고 생각하시면 됩니다.
Map<Long, Movie> 1차캐시 = new HashMap<>();
em.find()를 호출하면 먼저 1차 캐시에서 찾고, 없으면 데이터베이스에서 조회합니다.
1차 캐시는 데이터베이스 접근을 줄여줄 수 있고, 그만큼 좋은 성능을 보장해줍니다.
동일성 보장
같은 엔티티 인스턴스 두 개를 조회하는 코드를 살펴봅시다.
public void find() {
Long movieId = 1L;
Movie movie1 = em.find(Movie.class, movieId);
Movie movie2 = em.find(Movie.class, movieId);
}

movie1과 movie2는 같을까요?
정답은 당연히 같습니다.
em.find()로 반복해서 호출을 해도 영속성 컨텍스트는 1차 캐시에서 같은 값의 엔티티 인스턴스를 반환합니다.
동일성과 동일성에 대한 포스팅은 다음 포스팅을 참고해주세요.
오브젝트의 동일성과 동등성
자바에서 두 개의 오브젝트가 같은가라는 말은 주의해서 써야 합니다. 자바에서는 “같다"라는 표현에 다음과 같은 두 가지 의미가 담습니다. 동일성(identical) 두 개의 오브젝트가 완전히 같다는
kkoon9.tistory.com
쓰기 지연
엔티티 매니저는 트랜잭션을 커밋하기 직전까지 데이터베이스에 엔티티를 저장하지 않습니다.
대신 내부 쿼리 저장소에 INSERT SQL을 모아둡니다.
그리곤 트랜잭션을 커밋할 때 모아둔 쿼리를 데이터베이스에 보냅니다.
이것을 바로 트랜잭션을 지원하는 쓰기 지연이라고 합니다.
트랜잭션을 커밋하면 엔티티 매니저는 우선 영속성 컨텍스트를 플러시합니다.
플러시(flush) : 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화하는 작업
이 기능을 활용하여 bulk insert를 사용할 수 있습니다.
JPA에서의 bulk insert, bulk update test
배경 jpa는 insert는 save로, update는 변경감지를 통해 업데이트가 진행됩니다. 문제는 이 작업들이 단 건으로 진행된다는 점이죠. saveAll이 있으나 내부를 살펴보면 반복문을 통해 save로 저장해주는
kkoon9.tistory.com
변경 감지
변경 감지가 아닌 UPDATE 문으로 엔티티 수정을 한다고 가정해봅시다.
그렇게 되면 파라미터 별로 수정 쿼리가 많아지게 되고, 결국 비즈니스 로직이 SQL에 의존하게 됩니다.
이럴 때 필요한 게 변경 감지입니다.
변경 감지는 엔티티의 변경사항을 데이터베이스에 자동으로 반영하는 기능입니다.
스냅샷 : 엔티티를 영속성 컨텍스트를 보관할 때, 최초 상태를 복사해서 저장해두는 것
변경 감지는 플러시 시점에 스냅샷과 엔티티를 비교해서 변경된 엔티티를 찾습니다.
당연한 이야기지만, 변경 감지는 영속성 컨텍스트가 관리하는 영속 상태의 엔티티에만 적용됩니다.
지연 로딩
엔티티에서 해당 엔티티를 불러올 때 그 때 SQL을 날려 해당 데이터를 가져옵니다.
지연 로딩은 다룰 내용이 많아 다른 포스팅에서 다루겠습니다.
'Sping Framework > Spring JPA' 카테고리의 다른 글
[ChatGPT] queryDsl에서 CustomRepsitory 인터페이스를 따로 만드는 이유 (0) | 2023.08.09 |
---|---|
JPQL과 QueryDsl의 차이점에 대해서 (0) | 2023.02.28 |
엔티티의 정의와 생명주기(lifecycle) (0) | 2023.02.11 |
- Total
- Today
- Yesterday
- 테라폼
- 디자인패턴
- kotest
- Algorithm
- BOJ
- 클린 코드
- 디자인 패턴
- 이펙티브 자바
- 프로그래머스
- AWS
- node.js
- 이팩티브 자바
- BAEKJOON
- Effective Java
- 알고리즘
- 클린 아키텍처
- 정규표현식
- 객체지향
- kkoon9
- Kotlin
- JPA
- programmers
- Olympiad
- Spring
- MSA
- C++
- 코테
- Spring Boot
- Java
- 백준
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |