-
[JPA] 영속성 관리DEV/JPA 2024. 2. 22. 02:12
* 정보전달의 목적이 아닌 개인 스터디 정리 글 입니다.
강의 : 인프런 <자바 ORM 표준 JPA 프로그래밍 기본편>
교육자 : 김영한
영속성 컨텍스트
→ 엔티티를 영구 저장하는 환경
→ EntityManager.persist(entity);엔티티의 생명주기
- 비영속 : 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
ex )
//객체를 생성한 상태 (비영속 상태)
Member meber = new Member();
member.setId(100L);
member.setName("HelloJPA");
- 영속 : 영속성 컨텍스트에 관리되는 상태ex )
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
//객체를 저장한 상태 (영속상태)
em.persist(member); → DB에 저장된 상태는 아님
- 준영속 : 영속성 컨텍스트에 저장되었다가 분리된 상태ex )
//회원 엔티티를 영속성 컨텍스트에서 분리 (준영속 상태)
em.detach(member);
- 삭제 : 삭제된 상태ex )
//객체를 삭제한 상태(삭제 상태)
em.remove(member);영속성 컨텍스트의 이점
(1) 1차 캐시
ex 1)
em.persist(member); // 1차캐시에 저장
em.find(Member.class, 1L); // 1차캐시에서 조회ex 2)
Member find1 = em.find(Member.class , 1L); // db에서 조회
Member find2 = em.find(Member.class , 1L); // 1차캐시에서 조회
(2) 영속 엔티티의 동일성 보장
find1 == find2
→ 같은 트랜잭션안에서는 결과 true
(3) 트랜잭션을 지원하는 쓰기지연EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
transaction.begin();
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다
em.persist(member1);
em.persist(member2);
→ 1차캐시에 저장하는 동시에 쓰기지연 SQL저장소에 insert쿼리 생성
transaction.commit();→ 커밋하는 순간 데이터베이스에 INSERT SQL을 보냄
* persistence의 하이버네이트 옵션중 batch_size에 따라
쿼리를 저장해놓을수있는 사이즈를 정할수있음 (버퍼링같은기능)
(4) 엔티티 수정 (변경감지) dirty checkingmemberA.setUserName("ivory");
위와 같이 setter method 호출 후
em.update(memberA)같은 코드가 있어야하지않을까 ..? X
flush() > 엔티티와 스냅샷 비교 > 변화가 있으면 쓰기지연 SQL저장소에 update SQL 생성 > flush > commit
* 스냅샷 : DB에서 값을 읽어온 최초의 상태* 엔티티 삭제
em.remove(memberA);
→ 커밋시점에 삭제됨
플러시
영속성 컨텍스트의 변경내용을 데이터베이스에 반영
- 변경감지
- 수정된 엔티티 쓰기지연 SQL 저장소에 등록
- 쓰기지연 SQL 저장소의 쿼리를 데이터베이스에 전송 (등록,수정,삭제쿼리)
플러시하는법
- 직접호출 : em.flush()
- 자동호출 : 트랜잭션 커밋, JPQL 쿼리 실행
* 커밋 전 플러시를 한다고해서 1차 캐시에 있는것이 지워지는것은 아니고
쓰기지연SQL저장소에 있는것들이 DB에 반영되는것뿐임
* JPQL 쿼리의 경우 자동으로 flush된 후 JPQL이 실행됨
플러시 모드 옵션
em.setFlushMode(mode);
- FlushModeType.AUTO : 커밋이나 쿼리를 실행할 때 플러시 (디폴트)
- FlushModeType.COMMIT : 커밋할때만 플러시
* 가급적 기본값으로 두고 사용
플러시는
- 영속성 컨텍스트를 비우지않음
- 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화하는 작업
- 트랜잭션이라는 작업단위가 중요 → 커밋 직전에만 동기화하면됨
준영속상태
- 영속 -> 준영속 상태로 가는것
- 영속 상태의 엔티티가 영속성 컨텍스트에서 분리
- 영속성 컨텍스트가 제공하는 기능을 사용못함
준영속 상태로 만드는 방법
- 특정 엔티티만 준영속 상태로 전환 : em.detach(entity)
- 영속성 컨텍스트를 완전히 초기화 : em.clear() → 1차캐시 초기화
- 영속성 컨텍스트를 종료 : em.close()'DEV > JPA' 카테고리의 다른 글
[JPA] 다양한 연관 관계 매핑 ( N:1 / 1:N / 1:1 / N:M ) (1) 2024.04.04 [JPA] 연관관계 매핑 기초 (0) 2024.03.29 [JPA] 엔티티 매핑 (0) 2024.03.07 [JPA] 시작하기, 기본 설정 (0) 2024.02.14 [JPA] 등장 배경, 개념 정리 (2) 2024.02.11