티스토리 뷰
목차
1. 엔티티 생명주기
2. 엔티티 매니저 팩토리와 엔티티 매니저
3. 영속성 컨텍스트
4. 플러시
5. 준영속
1. 엔티티 생명주기
비영속 (new/transient) : 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
영속 (managed) : 영속성 컨텍스트에 관리되는 상태
준영속 (detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태
삭제 (removed) : 삭제된 상태
2. 엔티티 매니저 팩토리와 엔티티 매니저
- 엔티티 매니저 팩토리는 하나만 생성해서 애플리케이션 전체에 서 공유
- 엔티티 매니저는 쓰레드간에 공유X (사용하고 버려야 한다).
- JPA의 모든 데이터 변경은 트랜잭션 안에서 실행
EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpabasic");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
// 트랜잭션 시작
tx.begin();
try {
// ...
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
// 트랜잭션 종료
tx.commit();
3. 영속성 컨텍스트
1) 1차 캐시
1차 캐시를 먼제 확인해 엔티티를 가져온다. (select 쿼리가 실행되지 않음)
1차 캐시에 없는 경우 DB에서 엔티티를 가져온다. (select 쿼리 실행)
// 엔티티를 영속화
em.persist(memberA);
// 1차 캐시에서 조회
Member memberA = em.find(Member.class, "memberA");
// DB에서 조회
Member memberC = em.find(Member.class, "memberC");
2) 동일성(identity) 보장
트랜잭션 내에서의 엔티티 동일성을 보장한다.
Member memberA1 = em.find(Member.class, "memberA");
Member memberA2 = em.find(Member.class, "memberA");
System.out.println(memberA1 == memberA2); //동일성 비교 true
3) 트랜잭션을 지원하는 쓰기 지연
트랜잭션 커밋 시점에 flush와 commit이 실행된다.
일정 size의 SQL을 모았다가 flush하는 방법으로 성능 최적화에 사용할 수 있다. (hibernate.jdbc.batch_size 옵션)
flush() : 쓰기지연 SQL 저장소에 저장되어 있는 memberA [insert SQL]을 DB로 전달하고 commit한다. (DB 반영)
em.persist(memberA); // 영속화
transaction.commit(); // flush() 자동 호출
4) 변경 감지(Dirty Checking)
최초로 엔티티를 읽어온 시점에 스냅샷을 저장한다.
flush() 시점에 스냅샷과 비교해 [update/delete SQL] 을 만들어 쓰기지연 SQL 저장소에 저장하고 DB로 전달한다.
// 엔티티 영속화
Member memberA = em.find(Member.class, "memberA"); // 스냅샷 저장
Member memberB = em.find(Member.class, "memberB");
// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);
// 영속 엔티티 삭제
em.remove(memberB);
transaction.commit(); // flush() 자동 호출
변경 감지 vs merge
준영속 상태의 엔티티를 수정하는 방법은 두 가지가 있다.
(1) 변경 감지 : 엔티티를 영속화한 후 필드를 변경한다.
Item item = em.findById(param.getId());
item.setName("name"); //필드를 변경할 때는 setter 보다는 의미있는 메서드를 사용해야 함
트랜잭션 커밋 시점에 update 쿼리가 실행된다.
(2) merge
Item item = em.merge(param);
param의 id 를 통해 데이터베이스에서 엔티티를 조회한다.
param의 필드 값을 찾은 엔티티에 모두 적용한 후 변경된 엔티티를 영속화하고 리턴한다.
param에 값이 null인 필드가 있으면 데이터베이스에 null 값이 저장될 우려가 있다.
Spring Data Jpa의 save() 메소드를 호출할 때 준영속 상태의 엔티티를 대상으로 사용하면 merge()가 호출된다.
4) 지연 로딩(Lazy Loading)
작성 예정.
4. 플러시
1) 플러시 발생시 실행
- 변경 감지(Dirty Checking)
- SQL 전송
2) 플러시 호출 시점
- em.flush() - 직접 호출
- 트랜잭션 커밋 - 플러시 자동 호출
- JPQL 쿼리 실행 - 플러시 자동 호출
5. 준영속
영속성 컨텍스트에서 관리하지 않게 변경됨(영속 -> 준영속)
- em.detach(entity) : 특정 엔티티만 준영속 상태로 전환
- em.clear() : 영속성 컨텍스트를 완전히 초기화
- em.close() 영속성 컨텍스트를 종료
출처
https://www.inflearn.com/course/ORM-JPA-Basic 자바 ORM 표준 JPA 프로그래밍 - 기본편(김영한)
'ORM > JPA' 카테고리의 다른 글
[JPA] 6. 프록시와 연관관계 관리 (0) | 2021.12.14 |
---|---|
[JPA] 5. 고급 매핑 (0) | 2021.12.01 |
[JPA] 4. 다양한 연관관계 매핑 (0) | 2021.11.29 |
[JPA] 3. 연관관계 매핑 (0) | 2021.11.09 |
[JPA] 2. 엔티티 매핑 (0) | 2021.11.07 |
- Total
- Today
- Yesterday
- Spring
- named query
- clean code
- Git
- 스프링 카프카 컨슈머
- 육각형 아키텍처
- java8
- 이벤트 스토밍
- 트랜잭셔널 아웃박스 패턴
- 학습 테스트
- MySQL
- mockito
- 계층형 아키텍처
- 폴링 발행기 패턴
- kafka
- 클린코드
- http
- spring rest docs
- Spring Boot
- ATDD
- 스프링 예외 추상화
- TDD
- Spring Data JPA
- Stream
- H2
- JPA
- Ubiquitous Language
- 마이크로서비스 패턴
- 도메인 모델링
- HTTP 헤더
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |