영속성 컨텍스트
💡 엔티티를 영구 저장하는 환경, 가상의 DB 역할
엔티티 생명주기
비영속(new/transient) : 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
Member member = new Member();
member.setId("member1");
member.setUsername("홍길동");
영속(managed) : 영속성 컨텍스트에 관리되는 상태
EntityManager em = EntityManagerFactory.createEntityManager();
em.getTransaction().begin();
Member member = new Member();
member.setId("member1");
member.setUsername("홍길동");
// 객체를 영속성 컨텍스트에 저장(영속)
em.persist(member);
준영속(detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태
//member 엔티티를 영속성 컨텍스트에서 분리(준영속)
em.detach(member);
// 객체를 삭제한 상태(삭제)
em.remove(member);
영속성 상태의 장점
1. 1차 캐시(영속성 컨텍스트)
영속성 컨텍스트 내부에 있음
엔티티 매니저로 조회하거나 변경하는 모든 엔티티는 1차 캐시에 저장됨
같은 트랜잭션 내에서 엔티티를 캐싱하고 재사용할 때 사용
Map<KEY, VALUE>로 저장. Find() 메소드 호출 시 영속성 컨텍스트의 1차 캐시 조회
끄고 켤 수 있는 옵션이 아님
2차 캐시
1차 캐시를 여러 곳에서 하면 데이터베이스 접근 횟수를 획기적으로 줄이지 못하니까 2차 캐시를 사용
애플리케이션 전체 또는 여러 트랜잭션 간에 사용
애플리케이션을 종료할 때까지 유지됨
엔티티 매니저를 통해 데이터를 조회할 때 우선 2차 캐시에서 찾고 없으면 데이터베이스에서 찾음
객체를 직접 반환하지 않고 복사본을 만들어서 반환함
2. 동일성 보장
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.println(a==b) // true
3. 쓰기 지연
쓰기 지연 SQL 저장소에 SQL을 쌓아두고 트랜잭션 커밋 시점에 저장된 SQL 문 flush하여 데이터베이스 반영
4. 변경 감지
1차 캐시에 데이터베이스에서 처음 불러온 엔티티의 스냅샷 저장 및 커밋 시점에 변경 내용을 반영. 즉, update문을 호출하지 않아도 됨
5. 지연 로딩
연관 관계 매핑되어 있는 엔티티를 조회 시 우선 프록시 객체를 반환하고, 실제로 필요할 때 쿼리를 날려 가져오는 기SMD
필요할 때 데이터를 가져오는 기능