영속 상태인 Entity, 즉, 영속 컨텍스트에서 관리되는 Entity는 조회 시 1차 캐시에서 가져온다.
1차 캐시에 저장되어 있지 않은 Entity는 데이터베이스에서 조회한 후 1차 캐시에 저장한다.
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
//1차 캐시에 저장됨(영속)
em.persist(member);
//1차 캐시에서 조회
Member findMember = em.find(Member.class, "member");
// 영속 컨텍스트에 없는 Entity는 DB에서 조회
Member findMember2 = em.find(Member.class, "member2");
동일성(identity) 보장
Member member = new Member();
member.setId(1L);
member.setName("member1");
em.persist(member);
Member findMember1 = em.find(Member.class,1L);
Member findMember2 = em.find(Member.class, 1L);
System.out.println("findMember1 == findMember2 : " + (findMember1 == findMember2)); // true
트랜잭션을 지원하는 쓰기 지연(Transactional write-behind)
엔티티 등록 시 persist() 메서드로 1차 캐시에 저장, 관리하고 커밋 시점에 INSERT SQL을 보낸다.
em.persist(memberA);
em.persist(memberB);
//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
transaction.commit(); // [트랜잭션] 커밋
변경 감지(Dirty Checking)
1차 캐시에서 관리되는 Entity는 데이터 수정 시 자동으로 변경을 감지하고 커밋 시점에 INSERT SQL와 UPDATE SQL을 보낸다.
tansaction 안에서 데이터 변경할 때 변경 감지가 이루어지는 것이니 헷갈리지 말자.
flush
영속성 컨텍스트의 변경내용을 데이터베이스에 반영한다.
영속성 컨텍스트의 Entity들을 플러시 하는 방법 1. em.flush() : 직접 호출 2. 트랜잭션 커밋 : 플러시 자동 호출 3. JPQL 쿼리 실행 : 플러시 자동 호출
플러시가 호출되었다고 해서 영속성 컨텍스트의 Entity들이 사라지는 건 아니다.
플러시 모드 옵션 : em.setFlushMode(옵션), (거의 기본 옵션으로 사용하니 참고로만 알자) - FlushModeType.AUTO : 기본 옵션, 커밋이나 쿼리를 실행할 때 플러시 - FlushModeType.COMMIT : 커밋할 때만 플러시
준영속 상태
영속 상태의 Entity가 영속성 컨텍스트에서 분리(detach)된 상태
영속성 컨텍스트가 제공하는 기능을 사용하지 못한다.
준영속 상태로 만드는 방법 - em.detach(entity) : 특정 엔티티만 준영속 상태로 전환 - em.clear() : 영속성 컨텍스트를 완전히 초기화(1차 캐시에 있는 엔티티들을 준영속 상태로 전환 - em.close() : 영속성 컨텍스트를 종료