-
영속성 컨텍스트JPA/JPA 기본 2023. 7. 11. 18:03
영속성 컨텍스트란 엔티티를 영구 저장하는 환경이라는 뜻이다.
엔티티 매니저를 통해서 영속성 컨텍스트에 접근하는데, 엔티티 매니저를 생성하면 영속성 컨텍스트가 생기게 된다.
JPA의 내부가 어떻게 동작하는지에 대한 내용이 영속성 컨텍스트라 할 수 있다.
엔티티의 생명주기
- 비영속 : 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
- 영속 : 영속성 컨텍스트에 관리되는 상태
- 준영속 : 영속성 컨텍스트에 저장되었다가 분리된 상태
- 삭제 : 삭제된 상태
영속 상태로 만들어주는 방법은 2가지가 있다. 첫 번째로 persist를 하는 것이고, 두 번째로 1차 캐시에 없는 엔티티를 find로 찾아오게 되면 자동으로 1차 캐시에 넣어주면서 영속 상태가 되는 것이다.
영속성 컨텍스트의 이점
- 1차 캐시
- 동일성 보장
- 트랜잭션을 지원하는 쓰기 지연
- 변경 감지
1차 캐시
동일한 트랜잭션 안에서 한 번 조회했던 엔티티를 다시 조회한다면 쿼리가 날라가지 않는다.
db에 바로 데이터를 넣기 전에 1차 캐시라는 곳이 있다.
EntityManager em = emf.createEntityManager(); EntityTransaction transaction = em.getTransaction(); //엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다. transaction.begin(); // [트랜잭션] 시작 em.persist(memberA); em.persist(memberB); //여기까지 INSERT SQL을 데이터베이스에 보내지 않는다. //커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다. transaction.commit();
트랜잭션이 생성되고 persist를 하게되면 db에 쿼리를 날리는 것이 아니라 1차 캐시라는 곳에 key값과 엔티티를 넣어준다. 그리고 트랜잭션이 커밋되는 순간에 db에 쿼리를 보내주는 것이다.
동일성 보장
Member a = em.find(Member.class, "member1"); Member b = em.find(Member.class, "member1"); System.out.println(a == b);
같은 member를 조회할 때 객체 a와 b는 같은 값을 가진다.
트랜잭션을 지원하는 쓰기 지연(버퍼링)
아까 설명한 것처럼 1차 캐시에 엔티티들을 저장해두다가 트랜잭션이 커밋되는 시점에 db에 쿼리를 보낸다.
한 번에 쿼리를 보낼 수 있다는 이점이 있다.
변경 감지
업데이트 할 때에 일일이 persist를 하지 않아도 JPA가 자동으로 인식해서 업데이트 해준다.
(변경 감지에 대해서는 이전에 따로 포스팅이 있음)
플러시
플러시란 영속성 컨텍스트의 변경내용을 데이터베이스에 반영해주는 것이다.
트랜잭션이 커밋되는 상황에서 플러시가 자동으로 호출되어서 db에 쿼리가 나가게 된다.
트랜잭션이 커밋되기 전에 플러시를 하고싶으면 em.flush()로 직접 호출하면 된다. 또한 JPQL 쿼리를 실행시키면 자동으로 플러시가 호출되는 것이다.
영속성 컨텍스트를 플러시하는 방법
- em.flush() - 직접 호출
- 트랜잭션 커밋 - 플러시 자동 호출
- JPQL 쿼리 실행 - 플러시 자동 호출
플러시는 영속성 컨텍스트를 비우지 않고 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화해준다.
'JPA > JPA 기본' 카테고리의 다른 글
즉시로딩과 지연로딩 (0) 2023.07.11 프록시 (0) 2023.07.11 상속관계 매핑 (0) 2023.07.11 다양한 연관관계 매핑 (0) 2023.07.11 연관관계 매핑 - 단방향, 양방향 연관관계 (0) 2023.07.11