@Test
@DisplayName("영속성 컨텍스트가 비어있으면 em.find는 DB에도 찔러본다")
void test1() {
// 영속성 컨텍스트, DB에 모두 member 저장 (IDENTITY 전략)
final Member member = new Member("kth990303", "[email protected]", Platform.KAKAO, "1");
final Long memberId = memberRepository.save(member)
.getId();
// 영속성 컨텍스트 비워줌
em.flush();
em.clear();
System.out.println("============================================");
em.find(Member.class, memberId);
}
@Test
@DisplayName("영속성 컨텍스트가 비어있으면 em.remove는 예외를 발생시킨다 -> 준영속 상태 엔티티에 접근하므로")
void test2() {
// 영속성 컨텍스트, DB에 모두 member 저장 (IDENTITY 전략)
final Member member = new Member("kth990303", "[email protected]", Platform.KAKAO, "1");
memberRepository.save(member);
// 영속성 컨텍스트 비워줌
em.flush();
em.clear();
System.out.println("===========================");
assertThatThrownBy(() -> em.remove(member));
}
memberRepository.delete()
문은 Spring Data JPA의 메서드이다.@Test
@DisplayName("em.remove는 1차 캐시가 비어있을 때 delete 쿼리 뿐만 아니라 select 쿼리도 발생시킨다")
void test3() {
// 영속성 컨텍스트, DB에 모두 member 저장 (IDENTITY 전략)
final Member member = new Member("kth990303", "[email protected]", Platform.KAKAO, "1");
memberRepository.save(member);
// 영속성 컨텍스트 비워줌
em.flush();
em.clear();
System.out.println("===========================");
em.remove(member);
em.flush();
em.clear();
}
@Test
@DisplayName("jpql의 delete는 1차 캐시가 비어있을 때 delete 쿼리 뿐만 아니라 select 쿼리도 발생시킨다")
void test4() {
// 영속성 컨텍스트, DB에 모두 member 저장 (IDENTITY 전략)
final Member member = new Member("kth990303", "[email protected]", Platform.KAKAO, "1");
memberRepository.save(member);
// 영속성 컨텍스트 비워줌
em.flush();
em.clear();
System.out.println("===========================");
memberRepository.delete(member);
em.flush();
em.clear();
}
@Test
@DisplayName("jpql의 deleteAll은 1차 캐시가 비어있을 때 delete 쿼리 뿐만 아니라 select 쿼리도 발생시킨다")
void test5() {
// 영속성 컨텍스트, DB에 모두 member 저장 (IDENTITY 전략)
final Member member = new Member("kth990303", "[email protected]", Platform.KAKAO, "1");
memberRepository.save(member);
System.out.println("===========================");
memberRepository.deleteAll();
em.flush();
em.clear();
}
@Test
@DisplayName("jpql의 deleteAll은 DB와 영속성 컨텍스트 모두 비어있을 때에도 select 쿼리를 발생시킨다")
void test6() {
memberRepository.deleteAll();
em.flush();
em.clear();
}
JpaRepository의 구현체인 SimpleJpaRepository의 delete method를 보면 em.find()
작업을 거치는 것을 알 수 있다. 이 말인 즉슨, 1차 캐시에 있을 경우 영속성 컨텍스트의 값을, 1차 캐시에 없을 경우 select 쿼리를 날려서 찾아온다.
@Override
@Transactional
@SuppressWarnings("unchecked")
public void delete(T entity) {
Assert.notNull(entity, "Entity must not be null!");
if (entityInformation.isNew(entity)) {
return;
}
Class<?> type = ProxyUtils.getUserClass(entity);
T existing = (T) em.find(type, entityInformation.getId(entity));
// if the entity to be deleted doesn't exist, delete is a NOOP
if (existing == null) {
return;
}
em.remove(em.contains(entity) ? entity : em.merge(entity));
}
em.find()
를 할 경우 select 쿼리를 쓰기지연저장소에서 커밋하기 전에 날린다