JPA에서 가장 중요한 2가지
- 객체와 관계형 데이터베이스 매핑
- 영속성 컨텍스트
엔티티 매니저 팩토리와 엔티티 매니저
영속성 컨텍스트
- “엔티티를 영구 저장하는 환경”
- 논리적인 개념, 눈에 보이지 않음
EntityManager.persist(entity);
→ DB에 저장하는 것이 아니라 영속성 컨텍스트에 저장
EntityManager를 생성하면 영속성 컨텍스트가 1:1로 생성
→ EntityManager 안에 영속성 컨텍스트가 보이지 않는 공간에 생김
엔티티의 생명주기
- 비영속 (new/transient)
영속성 컨텍스트와 관계없는 새로운 상태
객체를 생성한 상태 - 세팅만 한 상태
Member member = new Member();
member.setId(100L);
member.setName("HelloJPA");
- 영속 (managed)
영속성 컨텍스트에 관리되는 상태
객체를 저장한 상태
em.persist(member);
바로 DB에 쿼리가 날아가는 것 X
tx.commit(); 하는 시점에 날아감
- 준영속 (detached)
영속성 컨텍스트에 저장되었다가 분리된 상태
em.detach(member);
- 삭제 (removed)
삭제된 상태
em.remove(member);
영속성 컨텍스트의 이점
1. 1차 캐시
내부에 1차 캐시를 들고 있다. 1차 캐시 == 영속성 컨텍스트
내부의 1차 캐시는 entity 자체(member)가 값이 된다.
- 조회
Member findMember = em.find(Member.class, "member1");
-> JPA는 영속성 컨텍스트에서 1차 캐시를 먼저 확인함(캐시값 조회)
Member findMember = em.find(Member.class, "member2");
-> 1차 캐시에 없음 -> DB조회 -> 1차 캐시에 저장 -> member2 반환
2. 영속성 엔티티의 동일성 보장
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member2");
System.out.println(a == b) // 동일성 비교 true
3. 엔티티 등록 - 트랜잭션을 지원하는 쓰기 지연
em.persist(memberA);
em.persist(memberB);
/* 여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
영속성 컨텍스트에 있는 쓰기 지연 SQL 저장소에 INSERT SQL를 쌓아둔다 */
transcation.commit(); // 커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
// 쓰기지연 SQL 저장소에 있던 애들이 flush 되면서 날아가 실제 DB 트랜잭션이 커밋된다.
4. 엔티티 수정 - 변경 감지
// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");
// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);
// em.update(member) 이런 코드 x
transaction.commit();
JPA transaction commit
- 내부적으로 flush 호출됨
- 엔티티와 스냅샷 비교(스냅샷 - 값을 읽어온 최초 시점의 상태)
- 변경된 부분 있을시 UPDATE 쿼리를 쓰기 지연 SQL 저장소에 만들어 둔다.
- 데이터베이스에 반영하고 commit
5. 엔티티 삭제
em.remove(memberA);
플러시
영속성 컨텍스트의 변경 내용을 데이터베이스에 반영
- 플러시 발생
변경 감지
수정된 엔티티를 쓰기 지연 SQL 저장소에 등록
쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송(등록, 수정, 삭제 쿼리)
- 영속성 컨텍스트를 플러시 하는 방법
em.flush() → 직접 호출
트랜잭션 커밋 → 플러시 자동 호출
JPQL 쿼리 실행 → 플러시 자동 호출
- 플러시 모드 옵션
em.setFlushMode(FlushModeType.COMMIT)
FlushModeType.AUTO → 커밋이나 쿼리 실행할 때 플러시 (기본값)
FlushModeType.COMMIT → 커밋할 때만 플러시
플러시는
영속성 컨텍스트를 비우지 않음
영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화
트랜잭션이라는 작업 단위가 중요 → 커밋 직전에만 동기화하면 됨
준영속 상태
- 영속 → 준영속
- 영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)
- 영속성 컨텍스트가 제공하는 기능을 사용 못함
준영속 상태로 만드는 방법
- em.detach(entity) → 특정 엔티티만 준영속 상태로 전환
- em.clear() → 영속성 컨텍스트를 완전히 초기화
- em.close() → 영속성 컨텍스트를 종료
참고 강의 :
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의
JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런
www.inflearn.com
'JPA > 자바 ORM 표준 JPA 프로그래밍 - 기본편' 카테고리의 다른 글
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 5. 연관관계 매핑 기초(2) (0) | 2022.12.29 |
---|---|
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 5. 연관관계 매핑 기초(1) (0) | 2022.12.28 |
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 4. 엔티티 매핑 (0) | 2022.12.01 |
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 2. JPA 시작 (0) | 2022.11.28 |
[자바 ORM 표준 JPA 프로그래밍 - 기본편] 1. JPA 소개 (0) | 2022.11.27 |