https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
JPA의 구동 방식
Persistence 클래스에서 설정 정보를 조회 한다.
META-INF/persistence.xml
Persistence는 EntityManagerFactory를 생성한다.
EntityManagerFactory는 EntityManager를 생성한다.
- EntityManage는 쓰레드간 공유가 안됨 (쓰고 버려야 함.)
- JPA의 모든 데이터 변경은 transaction 안에서 이루어져야 한다.
JPQL
- JPA의 모든 데이터 변경은 transaction 안에서 이루어져야 한다.
- EntityManage는 쓰레드간 공유가 안됨 (쓰고 버려야 함.)
테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
SQL을 추상화해서 특정 데이터베이스 SQL에 의존 X
JPQL을 한마디로 정의하면 객체 지향 SQL
영속성 컨텍스트
- 논리적인 개념
- EntityManager를 통해서 PersistenceContext가 1:1로 생성 됨.
Entity의 생명주기
- 비영속 (new/transient)
- 영속성 컨텍스트와 관계가 없는 상태
- 영속(managed)
- 영속성 컨텍스트에 관리되는 상태
- 준영속(detached)
- 영속성 컨텍스트에 저장되었다가 분리된 상태
- 삭제(removed)
- 삭제된 상태
비영속
Member member = new Member();
member.setId(1L)
member.setName("seungdols")
영속
Member member = new Member();
member.setId(2L);
member.setName("seungdols2");
entityManager.persist(member); // 영속 상태
transaction.commit();
준영속
entityManager.detach(member);
삭제
entityManager.remove(member);
1차 캐시
- 영속성 컨텍스트에 저장이 되면, 우선 1차 캐시에 저장이 되어, 1차 캐시에서 응답 됨.
- 만약, 영속성 컨텍스트에 없으면, DB 조회 후 1차 캐시에 저장하고, 반환 하는 구조를 갖는다.
- 다만, Transaction 안에서만의 짧은 주기의 캐시이므로 성능상의 이점이 엄청 크진 않을 수 있다.
영속 Entity의 동일성 보장
- 1차 캐시로 반복 가능한 읽기 등급의 트랜잭션 격리 수준을 어플리케이션에서 제공
트랜잭션을 지원하는 쓰기 지연
entityManager.persist(memberA);
entityManager.persist(memberB);
transaction.commit(); // 커밋 시점에 DB에 SQL이 전송이 된다.
변경 감지 (Dirty Checking)
Entity와 스냅샷 데이터를 비교 하고, Update를 자동적으로 반영
flush
영속성 컨텍스트의 변경내용을 데이터베이스에 반영
영속성 컨텍스트를 비우지 않음.
트랜잭션 단위가 중요한데, commit 직전에만 동기화 하면 됨.
flush 절차
- 변경 감지
- 수정 된 entity 쓰기 지연 SQL 저장소에 등록
- 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스 전송
flush 하는 방법은?
- flush() - 직접 호출
- transaction.commit() - flush 자동 호출
- JPQL 쿼리 실행 - flush 자동 호출
- JPQL은 실제 Query로 전송 되기 때문에, commit을 기다리기엔 Entity 영속성과 DB와 정합성이 안맞기 때문, 그래서 flush가 자동적으로 일어남.
준영속 상태
detach()
함수로 특정 객체를 영속성에서 제외 시킬 수 있음- 혹은
clear()
로 모든 컨텍스트를 비울 수 있다.
반응형