영속성 컨텍스트의 이점
JPA에서 가장 중요한 개념인 영속성 컨텍스트!
영속성 컨텍스트의 가장 중요한 특징은 1차 캐시이다.
EntityManager.persist()를 통해 영속성 컨텍스트 관리를 받는 엔티티는 1차 캐시라는 Map 형태의 저장 공간에 저장된다.
이때 key는 pk(primary key), value는 엔티티 객체 (=member) 가된다.
1차 캐시 동작 흐름
1. em.persist() : 영속성 부여 (1차 캐시 저장)
2. em.find() : 1차 캐시에서 primaryKey로 member 객체 조회
*2-2. 1차 캐시 조회 시 객체가 없는경우 DB에 접근해서 조회
2-3. DB에 조회한 값을 1차 캐시에 저장.
2-4. 반환.
3. tx.commit() -> 트랜잭션 커밋. 커밋과 동시에 flush() 발생 -> insert 문 실행.
1차 캐시 예제1. - 1차 캐시에 엔티티가 저장된 경우
//비영속
Member member = new Member();
member.setId(1L);
member.setName("chan");
//영속
em.persist(member);
Member findedMember = em.find(Member.class, 1L);
System.out.println("findedMember.getId() = " + findedMember.getId());
tx.commit();
위 예제를 통해 1차캐시에서 조회된 결과를 가져오는지 확인해 보자.
아래 결과에서 커밋 전에 찍은 findedMember의 ID값이 INSERT쿼리 보다 먼저 찍히는 이유가 바로 find() 조회 시 1차 캐시에서 조회한 member 객체를 가져왔기 때문이다.
findedMember.getId() = 1
Hibernate:
/* insert jpashop.jpashop.domain.Member
*/ insert
into
Member
(city, USERNAME, street, TEAM_ID, zipcode, MEMBER_ID)
values
(?, ?, ?, ?, ?, ?)
1차 캐시 예제2 - 1차 캐시에 저장된 엔티티가 없는 경우
// 1. 1차캐시에 없음. DB에서 조회 후 1차 캐시에 저장.
Member member1 = em.find(Member.class, 1L);
System.out.println("member1.getId() = " + member1.getId());
// 2. 1차 캐시 조회
Member member2 = em.find(Member.class, 1L);
System.out.println("member2.getName() = " + member2.getName());
tx.commit();
결과를 확인해보면 select 쿼리가 하나만 나간 것으로 첫 번째 조회에서 1차 캐시에 member를 저장하고,
2번째 조회에서 1차 캐시에 저장된 엔티티를 가져온 것을 알 수 있다.
결과
Hibernate:
select
member0_.id as id1_0_0_,
member0_.name as name2_0_0_
from
Member member0_
where
member0_.id=?
member1.getId() = 1
member2.getName() = member1
1차 캐시의 이점
DB에 접근하기 전 1차 캐시를 먼저 조회해 저장된 객체를 가져오기 때문에 복잡한 비지니스 로직에서 DB와 커넥션을 맺는 비용을 절약할 수 있다.
*참고
1차 캐시는 엔티티 매니저가 생성한 하나의 트랜잭션 안에서만 유효하다.
트랜잭션이 끝나는 것과 동시에 영속성 컨텍스 영역이 닫히기 때문.
따라서 하나의 요청 내에서만 이용 가능하기 때문에 성능적으로 크게 이점이 되지는 않는다.
reference
자바 ORM 표준 JPA 프로그래밍 - 기본편
https://www.inflearn.com/course/lecture?courseSlug=ORM-JPA-Basic&unitId=21687&tab=note
'JAVA' 카테고리의 다른 글
[JPA] JPA 다양한 연관관계 매핑 - 일대다 관계(1:N) (1) | 2024.01.14 |
---|---|
[JPA] 영속성 컨텍스트의 이점 - 동일성 보장 (0) | 2024.01.10 |
[JPA] 엔티티의 생명주기 - 영속, 비영속, 준영속, 삭제 (0) | 2024.01.10 |
[JPA] 엔티티 매핑 - 기본 키 매핑 (0) | 2024.01.06 |
[JPA] JPA 필드와 컬럼 매핑 (0) | 2024.01.05 |