개발놀이터

JPA 영속성컨텍스트 본문

JPA/JPA

JPA 영속성컨텍스트

마늘냄새폴폴 2021. 8. 21. 15:44

*JPA에서 가장 중요한 2가지
1. 객체와 관계형 데이터베이스 매핑하기
2. 영속성 컨텍스트


*영속성 컨텍스트
정의 : 엔티티를 영구저장하는 환경 
디비에 저장한다는 개념이 아니라 영속성 컨텍스트를 통해서 엔티티를 영속화를 한다는것 = 영속성 컨텍스트에 저장한다는 것
엔티티 매니저는 영속성컨텍스트를 1대1로 가지고 있다. 영속성컨텍스트는 눈에 보이지 않는 논리적인 개념이다. 


*비영속
member 객체를 생성하고 엔티티매니저에 아무것도 넣지않은 상태 
Member member = new Member();
member.setId("member1");
member.setUsername("회원1"); 이렇게 JPA가 관여하지 않은 객체 생성의 상태


*영속
em.persist(member); 이런식으로 객체를 저장한 상태를 영속 상태라고 한다. 이 상태는 단지 객체를 저장한 상태이지 디비에 저장한 것은 아니다 디비에 저장은 트랜젝션이 커밋될때이다.


*준영속
em.detach(member); 이 상태는 회원 엔티티를 영속성 컨텍스트에서 분리시키는 상태이다. 이 상태가 바로 준영속 상태


*삭제
em.remove(member); 이 상태가 바로 삭제 상태


*JPA 1차 캐시
Member findMember = em.find(Member.class, "member1"); 이렇게 조회를 하면 JPA는 1차캐시를 뒤져서 엔티티가 있으면 그것을 반환해준다. 엔티티가 없다면 디비에서 조회해서 1차캐시에 저장하고 저장한 값을 반환해준다.


*영속 엔티티의 동일성 보장
1차캐시로 반복 가능한 읽기 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공 = JPA에서 같은 트랜잭션 안에서는 같은 것을 조회하면 그 두개의 값이 같다는 것을 보장해준다.


*엔티티 등록 (트랜잭션을 지원하는 쓰기 지연)
트랜잭션을 커밋하기 전까지 디비에 적용이 안된다. 
em.persist(memberA);
em.persist(memberB);
이렇게 영속성 컨텍스트에 1차캐시에 저장함과 동시에 쓰기지연 SQL저장소라는 곳에 SQL문들을 차곡차곡 쌓아놓는다. 그러다가 트랜잭션 커밋이 발동되면 그때 모아뒀던 SQL문들을 flush해서 디비에 저장한다.


*엔티티 수정 (변경 감지 = Dirty Checking)
영속 엔티티를 조회하고 영속 엔티티를 수정할 때 객체의 값만 바꿔주면 update쿼리를 자동으로 만들어준다. 원리가 뭘까?
1차 캐시에 엔티티를 모아둘 때 스냅샷이라는 것을 만들어 둔다. 스냅샷이 뭐냐하면 최초로 엔티티가 등록된 상태를 말한다. 즉 em.find(Member.class, 1) 이렇게 select쿼리로 1차 캐시에 값을 저장해둔 값이 혹여 setName을 사용해서 객체에 들어있는 값을 변경했다면 트랜잭션 커밋이 되는 순간 JPA는 이후에 엔티티랑 스냅샷을 일일히 비교하는 과정을 거친다. 그렇게 비교하다가 엔티티와 스냅샷이 일치하지 않으면 업데이트 쿼리를 만들어서 디비에 플러쉬한다.


*플러쉬
영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 것

영속성 컨텍스트를 플러쉬하는 방법
em.flush() = 직접 호출 (쓸일은 거의 없지만 나중에 테스트 할때 필요하다 알아두자)
트랜잭션 커밋 = 자동 호출
JPQL 쿼리 사용 = 자동 호출

플러쉬는
-영속성 컨텍스트를 비우지 않는다. (쓰기지연 SQL저장소에 있는 SQL문만 플러쉬하는 것이다)
-영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화
-트랜잭션이라는 작업 단위가 중요 -> 커밋 직전에만 동기화 하면 됨


*준영속 상태
-영속 -> 준영속
-영속 상태의 엔티티가 영속성 컨텍스트에서 분리 (detached)
-영속성 컨텍스트가 제공하는 기능을 사용 못함

'JPA > JPA' 카테고리의 다른 글

JPA 상속관계 매핑  (0) 2021.08.23
JPA 연관관계의 주인  (0) 2021.08.23
JPA 기본키 매핑  (0) 2021.08.21
JPA Entity 매핑  (0) 2021.08.21
JPA 시작하기  (0) 2021.08.21