영속성 컨텍스트의 뜻은 "엔티티를 영구 저장하는 환경" 이라는 뜻이다.
- em.persister(Entity)는 사실 DB에 저장하는 것이 아니라 영속성 컨텍스트에 저장하는 것이다.
- 영속성 컨텍스트는 논리적인 개념으로 눈에 보이지 않는다.
- 엔티티매니저를 통해서 영속성 컨텍스트에 접근 (엔티티매니저가 생기면 영속성 컨텍스트도 생긴다.)
엔티티 매니저 팩토리와 앤티티 매니저
J2SE 환경과 J2EE, 스프링 프레임워크 환경의 차이
*J2SE란 - Java 2 Standard Edition(기본 환경)
엔티티의 생명주기
비영속(new/transient)
비영속 컨텍스트와 전혀 관계가 없는새로운 상태
영속(managed)
영속성 컨텍스트에관리되는 상태
★영속성 상태란 정확하게 말하면 1차 캐시 저장소에 올라가있는 상태를 말하는 것이다.★
- persist(member) 이때 DB에 저장되는것은 아니다.
- DB에 Insert SQL을 날리는 시점은 persist()가 아닌 tx.commit() 트랙잭션 커밋순간이다. (DB에 Insert SQL을 날리고 실제 DB commit이 이뤄짐)
- 트랜잭션 commit()과 DB commit은 다른 것이다.
준영속(detached)
영속성 컨텍스트에 저장되었다가 분리된 상태
em.detach(member);
삭제(removed)
삭제된 상태
em.remove(member);
*준영속(detached)과 삭제(removed)의 차이
준영속(detached) 상태는 엔티티가 영속성 컨텍스트에서 분리된 상태를 말합니다.
즉, 영속성 컨텍스트가 엔티티를 더 이상 관리하지 않는 상태입니다.
이 상태에서는 엔티티를 변경해도 데이터베이스에는 반영되지 않습니다.
따라서, 준영속 상태에서 엔티티를 수정하고자 할 때에는, 해당 엔티티를 다시 영속성 컨텍스트에 추가해야 합니다.
이는 EntityManager의 merge() 메서드를 이용하여 가능합니다.
삭제(removed) 상태는 엔티티가 영속성 컨텍스트에서 삭제된 상태를 말합니다.
즉, 엔티티가 영속성 컨텍스트에서 제거된 후, 데이터베이스에서도 삭제됩니다.
이 상태에서는 엔티티를 수정하거나, 다시 추가할 수 없습니다.
영속성컨텍스트의 이점
- 동일성(identity) 보장
- 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)
- 변경 감지 (Dirty Checking)
- 지연 로딩 (Lazy Loading)
1차 캐시 저장소
- 영속성 컨텍스트 안에는 1차 캐시저장소가 존재한다.
- 1차 캐시의 자료구조는 key-value 형태이다.
- 1차 캐시는 트랜잭션이 끝난 후 영속성 컨텍스트를 지우기 때문에 성능 이점은 크게 없다.
- 1차 캐시에 값이 있으면 JPA는 굳이 DB에 접근하여 select문을 던지지않는다.
- 애플리케이션 전체에서 공유하는 캐시는 2차 캐시라한다.
엔티티 조회, 1차 캐시
//엔티티를 생성한 상태(비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
//엔티티를 영속, 1차 캐시에 저장됨
em.persist(member);
//1차 캐시에서 조회
Member findMember = em.find(Member.class, "member1");
데이터베이스에서 조회
Member findMember2 = em.find(Member.class, "member2");
영속 엔티티의 동일성 보장
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");
System.out.println(a == b); // true
1차 캐시로 반복 가능한 읽기(repeatable read) 등급의 트랜잭션 격리 수준을 DB 아닌 애플레케이션 차원에서 제공
트랜잭션을 지원하는 쓰기 지연 : 엔티티 등록
영속성 컨텍스트 안에는 1차 캐시저장소말고 쓰기 지연 SQL 저장소가 존재한다.
변경 감지(더티체킹) : 엔티티 수정
사실 1차 캐시에는 @id, Entity 컬럼 외에도 스냅샷 컬럼이 있다.
데이터를 조회하면 데이터를 최초로 조회한 시점의 상태를 스냅샷에 담아둔다.
tx.commit()이 실행되면 내부적으로 flush()가 동작되고 flush()가 동작되면 JPA는 Entity와과 스냅샷을 비교하여 다른점이 있으면 update 쿼리를 "쓰기 지연 SQL 저장소"에 만들어둔다.
그후에 flush, commit을 하여 DB에 반영한다.
엔티티 삭제
- em.remove()에 삭제 대상 엔티티를 넘겨주면 엔티티를 삭제한다.
- 물론 엔티티를 즉시 삭제하는 것이 아니라, 엔티티 등록과 비슷하게 삭제 쿼리를 쓰기 지연 SQL 저장소에 등록한다.
- 이 후 트랜잭션을 커밋하게되면 플러시가 호출되어 실제 데이터베이스에 삭제 쿼리를 전달하게 된다.
- em.remove(memberA)를 호출하는 순간 memberA는 영속성 컨텍스트에서 제거된다.
※ 출처: 인프런 김영한 JPA
'JPA' 카테고리의 다른 글
JPA - 필드와 컬럼 매핑 (0) | 2022.04.09 |
---|---|
JPA - 객체와 테이블 매핑 feat. 데이터베이스 스키마 자동생성 (0) | 2022.04.08 |
JPA - 준영속, 병합 (0) | 2022.04.08 |
JPA - 플러시 (0) | 2022.04.08 |
JPA를 배워야 하는 이유 (0) | 2022.04.06 |
댓글