-
[JPA] 영속성 컨텍스트스프링프레임워크/jpa 2021. 1. 13. 23:24
EntityManagerFactory
- Client의 요청이 올 때마다 EntityManager를 생성합니다.
EntityManager
- 데이터베이스 Connection을 사용해서 DB 처리를 진행합니다.
Entity의 생명 주기
- 비영속 (new/transient)
- 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
- 영속 (managed)
- 영속성 컨텍스트에 Entity가 관리되는 상태
- EntityManager.persist(entity)
- 아직 DB에 저장되지 않고 이후 transaction을 commit한 후에 DB에 저장됩니다.
- 준영속 (detached)
- 영속성 컨텍스트에 저장되었다가 분리된 상태
- 삭제 (removed)
- 삭제된 상태
EntityManager em = emf.createEntityManager(); EntiryTransaction tx = em.getTransaction(); tx.begin(); try { // 객체를 생성한 상태 (비영속) Member member = new Memb er(); member.setId("member1"); member.setUsername("회원1"); // 객체를 저장한 상태 (영속) // 지연 SQL 저장소에 저장하고 있다가 transaction commit 시점에 DB INSERT 쿼리가 전달됨 em.persist(member); // 회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태 // detach를 하면 transaction commit 시점에 DB INSERT 쿼리가 날라가지 않게됨 em.detach(member); // 객체를 삭제한 상태 (삭제) em.remove(member); tx.commit(); } catch(Exception e) { tx.rollback(); } finally { em.close(); }
영속성 컨텍스트(환경, 문맥)
- 엔티티를 영구 저장하는 환경 (논리적인 개념)
- EntityManager.persist(entity)
- DB에 저장하는것이 아니라 영속성 컨텍스트에 저장합니다.
- EntityManager는 영속성 컨텍스트를 데이터베이스 Transaction 단위로 만들고 Transaction이 끝나는 시점에 영속성 컨텍스트를 삭제합니다.
- EntityManager를 통해서 영속성 컨텍스트에 접근
- EntityManager를 생성하면 PersistenceContext가 1:1로 생성되어집니다.
- 영속성 컨텍스트가 필요한 이유
- 1차 캐시
- Map 종류의 1차 캐시가 존재하며 Key는 @Id로 설정한 필드의 값이 되고 Value는 해당 엔티티 객체가 됩니다.
- EntityManager를 통해서 조회 요청 시 바로 DB 조회를 시도하는 것이 아니라 1차 캐시에서 값을 조회하고 없을 경우 DB 조회를 시도합니다.
- 1차 캐시에 없는 경우 시나리오
- 1차 캐시를 조회
- 1차 캐시에 없으므로 DB 조회
- DB에서 조회한 데이터를 1차 캐시에 저장
- 반환
- 동일성(identity) 보장
- 같은 Transaction 안에서 동일한 entity를 조회 할 경우 동일성 비교(==)를 했을 때 true를 리턴합니다.
- 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)
- EntityManager.persist(entity)를 호출 시점에 쓰기 지연 SQL 저장소에 순서대로 저장하고 있다가 Transaction이 Commit되는 시점에 실제 DB에 INSERT QUERY가 전달되게 됩니다.
- 변경 감지 (Dirty Checking)
- Transaction Commit이 이루어질 때 동작 시나리오 (flush() 가 호출됨)
- 1차 캐시에 있는 엔티티와 스냅샷을 비교
- 스냅샷 : 최초 영속성 컨텍스트에 들어온 값
- 변경 된 부분에 대해 UPDATE SQL을 작성하고 쓰기 지연 SQL 저장소에 저장
- 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송
- 등록, 수정, 삭제 쿼리
- 데이터베이스 Commit
- 1차 캐시에 있는 엔티티와 스냅샷을 비교
- Transaction Commit이 이루어질 때 동작 시나리오 (flush() 가 호출됨)
- 지연 로딩 (Lazy Loading)
- 1차 캐시
inflearn 강좌 : 자바 ORM 표준 JPA 프로그래밍 - 기본편
'스프링프레임워크 > jpa' 카테고리의 다른 글
[JPA] @ElementCollection을 이용해서 Embeddable 타입의 Collection을 영속화 (0) 2021.01.29 [JPA] ID 참조와 조인 테이블을 이용한 단방향 M:N 매핑 (0) 2021.01.14 [JPA] JPA 관련 유용한 블로그 글 모음 (0) 2021.01.12 [JPA] QueryDsl에서 Pageable 객체를 이용한 Sort 방법 (6) 2020.09.09