Spring

영속성 컨텍스트의 1차 캐시는 어떻게 저장될까?

윤밥밥 2025. 2. 22. 17:17

영속성 컨텍스트의 1차 캐시

1차 캐시는 Map<PK, Entity> 형태로 관리된다.

이는 Hibernate의 PersistenceContext 의 구현체인 StatefulPersistenceContext 에서 찾아볼 수 있다.

entitiesByKey 필드 등을 보면 PK를 Key로 Object(엔티티)를 value로 관리하는 것을 볼 수 있다. 그리고 이 Key는 기본키를 저장한다

따라서 findById가 호출되면 내부적으로 우선 Map을 확인해 엔티티가 존재하는 지 확인하며, 있으면 Map에서 반환한다. 없으면 DB를 조회하여 Map 저장하고 엔티티를 반환한다.

 

만약 findByName() 등을 통해 조회하면 Name은 기본키가 아니므로 DB에서 조회해오게 된다. DB에서 조회해온 후에는 조회한 ID를 통해 같은 엔티티가 영속성 컨텍스트에 이미 저장되어 있는 지 확인한다.

만약 없으면 새로 저장하고, 있으면 영속성 컨텍스트에 저장하지 않고 이미 존재하는 것을 사용한다.

 

예시

	@Transactional
	public void test() {
		Room room2 = roomRepository.findById("1").get();
		Room room1 = roomRepository.findByName("room1").get();

		System.out.println(room1 == room2);
	}

위와 같은 로직을 실행한다고 하면 다음과 같이 동작한다.

  1. id가 1인 room을 1차 캐시에서 조회한다.
  2. id가 1인 room이 1차 캐시에 없기에 DB를 통해 조회한다.
  3. 가져온 데이터를 영속성 컨텍스트에 저장한다.
  4. 저장된 객체를 room2에 반환한다.
  5. name이 room1인 데이터를 DB에서 조회해온다.
  6. 가져온 데이터의 id를 통해 영속성 컨텍스트에 데이터가 존재하는 지 확인한다.
  7. 있으니까 영속성 컨텍스트에 저장하지 않는다.
  8. 기존의 room을 room1에 반환한다.
  9. room1과 room2는 같은 객체이므로 true가 출력된다.