twocowsong

엔티티 컨텍스트의 1차 캐시 본문

IT/JPA

엔티티 컨텍스트의 1차 캐시

WsCode 2022. 5. 2. 22:02

깃허브 정리 URL : https://github.com/sWineTake/jpa.git

 

GitHub - sWineTake/jpa: 자바 ORM 표준 JPA 프로그래밍 - 김영한

자바 ORM 표준 JPA 프로그래밍 - 김영한. Contribute to sWineTake/jpa development by creating an account on GitHub.

github.com

 

엔티티 조회

영속성 컨텍스트는 내부에 캐시를 가지고있습니다. 이를 1차 캐시라고 합니다.

영속 상태의 엔티티는 모두 이곳에 저장됩니다.

영속성 컨텍스트 내부에 Map이 하나있는데 키로 @Id로 매핑한 식별자고 값은 엔티티 인스터스입니다.

// 엔티티를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("홍길동");

// 엔티티를 영속
em.persist(member);

이 코드를 실행하면 1차 캐시에 회원 엔티티를 저장합니다.

회원 엔티티는 아직 DB에 저장되지 않은 상태입니다.

 

1차 캐시의 키는 식별자 값 입니다.

그리고 식별자의 값은 DB 기본키와 매핑되어 있습니다.

영속성 컨텍스트에 데이터를 저장, 조회하는 모든기준은 DB의 기본 키 값 입니다.

 

Member findMember = em.find(Member.class, "member1");

find() 메소드를 보면 첫 번째 파라미터는 엔티티 클래스 타입이고

두 번째는 조회할 엔티티 식별자 값 입니다. (즉 테이블에 기본키 값이 되겠죠?)

 

// EntityManager.find() 메소드 정의
public <T> T find(Class<T> var1, Object var2);

em.find()를 호출하면 먼저 1차 캐시에서 엔티티를 찾고

1차 캐시에 없으면 DB에 조회합니다.

 

// 엔티티를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("홍길동");

// 1차 캐시에 저장됨
em.persist(member);

// 1차 캐시에서 조회
Member findMember = em.find(Member.class, "member1");

만약 em.find()를 호출했는데 엔티티가 1차 캐시에 없으면 엔티티 매니저는 DB를 조회해서 엔티티를 생성합니다.

그리고 1차캐시에 저장한 후에 영속 상태의 엔티티를 반환합니다.

 


1. em.find(Member.class, "member2") 를 실행합니다.

2. member2가 1차 캐시에 없으므로 DB에서 조회합니다.

3. 조회한 데이터로 member2엔티티를 생성해서 1차 캐시에 저장합니다. (영속 상태)

4. 조회한 엔티티를 반환합니다.

 

member1, member2는 1차 캐시에 있습니다.

2개에 엔티티를 조회시에는 1차 캐시에서 바로 불러오기에 성능상 이점을 누릴 수 있습니다.


영속 엔티티의 동일성 보장

엔티티 인스턴스를 조회해서 비교해봅시다.

Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");

System.out.println(a == b);

 

여기서의 a == b는 참일까 거짓일까?

 

 

 

 

 

 

 

 

 

 

 

 

 

 

find를 반복해서 호출해도 영속성 컨텍스트는 1차 캐시에 있는 같은 엔티티를 계속적으로 반환하기에 둘은 같은 인스턴스이고 결과는 당연히 참입니다.

따라서 영속성 컨텍스트는 성능상 이점과 엔티티의 동일성을 보장합니다.

 

동일성과 동등성

동일성 : 실제 인스턴스가 같다. 따라서 참조값을 비교하는 == 비교의 값이 같습니다.

동등성 : 실제 인스턴스는 다를 수 있지만 인스턴스가 가지고 있는 값이 같습니다.

 

JPA는 1차 캐시를 통해 반복 가능한 읽기 등급의 트랜잭션 격리 수준을 DB가 아닌 애플리케이션 차원에서 제공한다는 장점이 있습니다. 추후 좀더 자세히 알아보겠습니다.

'IT > JPA' 카테고리의 다른 글

엔티티 수정 - 1  (0) 2022.05.04
영속성 컨텍스트 - 트랜잭션  (0) 2022.05.03
영속성 컨텍스트의 특징  (0) 2022.05.01
엔티티의 생명주기  (0) 2022.05.01
영속성 컨테스트  (0) 2022.05.01