영속성 컨텍스트
JPA에서 가장 중요한 2가지는 객체와 관계형 데이터베이스를 매핑하는 방법과(ORM) / 설계 - 정적
'영속성 컨텍스트' (JPA 가 내부적으로 동작하는 방식) 이다.
EntityManger.persist(entity);
persist 메소드는 사실 DB에 저장하는 것이 아닌 '영속성 컨텍스트' 에 저장하는 것이다.
'영속성 컨텍스트' 는 논리적인 개념이다. EntityManger 를 통해서 영속성 컨텍스트에 접근한다.
EntityManger 가 생성되면 PersistenceContext 라는 컨테이너가 생기고 이 안에 저장한다.
엔티티의 생명주기
비영속 : 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
// 객체를 생성한 상태
Member member = new Member();
member.setId("member1");
member.setUsernae("회원1");
영속 : 영속성 컨텍스트에 관리되는 상태. -> persist 등을 하면 영속 상태로 변경된다.
Member member = new Member();
member.setId("member1");
member.setUsernae("회원1");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(member); -> 실제로 DB에 저장되는 것이 아닌 PersistenceContext 에 저장! // Commit 해야 저장.
em.persist 를 통해 영속 컨텍스트에 저장하면 1차 캐시 안에 저장된다.
em.find 로 조회를 시도하면 DB 에 직접 접근해서 찾는 것이 아닌 영속 컨텍스트에서 먼저 찾는다.
만약 DB에는 "member2" 라는 값이 있지만 1차 캐시에 존재하지 않는다면 DB에서 해당 값을 조회 후 , 1차 캐시에 저장한다. 그리고 1차 캐시에서 해당 값을 반환한다.
-> 즉 , DB에 직접 접근하지 않고 1차 캐시를 이용해서 접근한다.
// 성능의 이점은 별로 없다.
Logic
수정 하는 경우 , 기존의 SQL 문은 update 문을 이용해서 쿼리문을 작성해주어야 한다.
하지만 JPA 는 setter 를 이용해서 수정하면 자동으로 update 가 된다.
(update 한 후 , persist 를 하지 않아도 되는가 ?
-> Collection 이라고 생각. 값을 변경하고 다시 집어넣지 않는다.)
흐름
Commit 하는 시점에 -> 내부에서 *flush() 호출 -> Entity 와 스냅샷 비교 ->
바뀐 부분이 있으면 쓰기 지연 SQL 저장소에 에 UPDATE QUERY 생성 -> flush() -> commit
Flush
Flush() 란 ?
영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 것을 뜻한다. (동기화)
* 영속성 컨텍스트를 flush() 하는 방법
1. em.flush() 직접 호출
2. 트랙잭션 커밋 - flush() 자동 호출
3. JPQL 쿼리 실행 - flush() 자동 호출
3. JPQL 쿼리 실행 시 flush() 가 자동 호출 되는 이유 :
em.persist 를 통해 저장하면 영속성 컨텍스트에 저장 -> 실제 DB에는 저장돼있지 않음 -> 조회하는 JPQL 쿼리를 실행하면 아직 DB 에 저장되지 않았으므로 조회 불가 -> 이를 막기 위해 JPQL 쿼리 실행하면 자동 flush()
* 해당 글은 'Infleran'의 김영한 강사님의 자료를 참조하였습니다.
'JPA Basic' 카테고리의 다른 글
JPA Basic - 6 (0) | 2021.12.30 |
---|---|
JPA Basic - 5 (0) | 2021.12.29 |
JPA Basic - 4 (0) | 2021.12.28 |
JPA Basic - 3 (0) | 2021.11.18 |
JPA Basic - 1 (0) | 2021.11.16 |
댓글