프로젝트 git url | github.com/rtef23/JpaStudy |
필요 | 1. docker 2. docker-compose |
프로젝트 정보 | mysql : 5.7 - docker image java : 1.8 |
영속성 컨텍스트(Persistence Context)
정의
- 엔티티를 영구 저장하는 환경
특징
- EntityManager를 이용하여 엔티티를 persist() 한다는 의미는
실제로 DB에 저장한다는 개념이 아니라 "영속성 컨텍스트에 저장한다"를 의미 - EntityManager instance의 경우, 트랜잭션과 라이프 사이클을 맞추는게 좋다.
- 1차 캐시
- ; entityManager에서 관리하는 key-value(식별자-엔티티)의 캐시
- 동일성 보장
- 1차 캐시에서 동일한 식별자에 대해서 동일한 instance를 리턴하기 때문에 동일성이 보장되게 된다.
Member member1 = entityManager.find(Member.class, 1L);
Member member2 = entityManager.find(Member.class, 1L);
//member1 == member2 instance의 동일성이 보장되게 된다.
- 변경 감지
- 1차 캐시에서 조회한 원본 엔티티를 스냅샷 형태로 저장하고
최종 flush시 영속(managed)된 엔티티와 원본 스냅샷을 비교하여 dirty를 감지하고
update 쿼리를 생성한다.
- 1차 캐시에서 조회한 원본 엔티티를 스냅샷 형태로 저장하고
Member member = entityManager.find(Member.class, 1L);
member.setName("test-2");
entityTransaction.commit();
//update 쿼리가 전송된다.
- 트랜잭션을 지원하는 쓰기 지연
- hibernate.jdbc.batch_size 옵션으로 한번에 전송할 쿼리 갯수를 조절할 수 있다.
- persist api를 사용하는 시점에서 DB로 쿼리를 전송하는 것이 아닌
transaction.commit() api를 사용하는 시점에서 DB로 쿼리를 전송
Member testMember1 = new Member(2L, "test-name2");
Member testMember2 = new Member(3L, "test-name3");
entityManager.persist(testMember1);
entityManager.persist(testMember2);
entityTransaction.commit();
//commit 시점에서 2개의 insert 쿼리가 전송됨
Member testMember1 = new Member(4L, "test-name2");
entityManager.persist(testMember1);
entityManager.remove(testMember1);
entityManager.persist(testMember1);
entityTransaction.commit();
//최종적으로 전송되는 쿼리는 insert 쿼리 1개
엔티티의 생명주기
- 비영속(new/transient)
- ; 영속성 컨텍스트와 전혀 관계가 없는 상태
- 영속(managed)
- ; 영속성 컨텍스트에 관리되는 상태
- 준영속(detached)
- ; 영속성 컨텍스트에서 저장되었다가 분리된 상태
- 삭제(removed)
- ; 삭제된 상태
- 논리 삭제여야 delete 쿼리를 만들 수 있기 때문에 해당 상태가 존재하는 듯 함.
- 참고
'JPA' 카테고리의 다른 글
[JPA] 6. 엔티티 매핑 (0) | 2021.01.05 |
---|---|
[JPA] 5. 영속성 컨텍스트 - 2 (0) | 2020.12.31 |
[JPA] 3. JPA 기본 api 사용 (0) | 2020.12.30 |
[JPA] 2. JPA 설정 (0) | 2020.12.30 |
[JPA] 1. JPA 소개 (0) | 2020.12.29 |