오봉이와 함께하는 개발 블로그
JPA - 플러시, 준영속 상태 본문
728x90
풀러시
플러시란 영속성 컨텍스트의 변경 내용을 DB에 반영하는 것이다.
플러시가 발생하면 자동으로 변경 감지하고 수정된 엔티티 쓰기 지연 SQL 저장소에 등록하며, 쓰기 지연 SQL 저장소의 쿼리를 DB에 전송한다.
플러시를 한다고 해서 1차 캐시가 삭제되지는 않는다, 단지 플러시는 쓰기 지연 SQL 저장소의 쿼리를 DB에 전송하는 역할을 한다.
영속성 컨텍스트를 플러시 하는 방법
- em.flush()
- 직접 호출
- 트랜잭션 커밋
- 플러시 자동 호출
- JPQL 쿼리 실행
- 플러시 자동 호출
JPQL 실행시 자동으로 플러시가 호출되는 이유는 앞서 persist한 객체가 있고, 해당 객체를 JPQL로 조회할 경우를 대비하는 것이다.
해당 객체를 영속성 컨텍스트에 등록은 했지만 DB에 값이 들어간 상태는 아니기 때문에 조회할 수 없어 오류가 발생하기 때문에 JPQL은 자동으로 플러시를 호출해 쓰기 지연 SQL 저장소의 쿼리를 DB에 전송하고, JPQL을 쿼리문으로 번역시켜 전송한다.
플러시는?
영속성 컨텍스트를 비우지 않고 영속성 컨텍스트의 변경내용을 DB에 동기화 한다.
플러시라는 메커니즘의 작동 근거는 트랜잭션이라는 작업 단위가 있기 때문인데, 이는 트랜잭션의 커밋 직전에만 동기화를 하면 되기 때문이다.
준영속 상태
영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)된 상태이다. 준영속 상태가 되면 영속 상태에서 사용할 수 있는 기능들을 사용할 수 없게 된다.
준영속 상태로 만드는 방법
- em.detach(entity)
- 특정 엔티티만 준영속 상태로 전환
- em.clear()
- 영속성 컨텍스트를 완전히 초기화
- em.close()
- 영속성 컨텍스트를 종료
em.detach(entity) 예제
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); // 앤티티 팩토리 매니저
EntityManager em = emf.createEntityManager(); // 앤티티 매니저
EntityTransaction tx = em.getTransaction(); // 트랜잭션
tx.begin();
try {
Member member = em.find(Member.class, 100L);
member.setName("ZZZZZ");
em.detach(member);
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
결과
Hibernate:
select
member0_.id as id1_0_0_,
member0_.name as name2_0_0_
from
Member member0_
where
member0_.id=?
setName() 메소드를 통해 엔티티의 값을 변경했지만, 업데이트 쿼리가 실행되지 않았다.
detach() 메소드로 엔티티를 준영속 상태로 변경했기 때문이다.
출처 : 인프런 김영한 지식공유자님의 스프링 부트와 JPA 실무 완전 정복 로드맵 강의
728x90
'BE > JPA' 카테고리의 다른 글
JPA - 실전 예제 1 - 요구사항 분석과 기본 매핑 (0) | 2022.06.24 |
---|---|
JPA - 필드와 컬럼 매핑, 기본 키 매핑 (0) | 2022.06.24 |
JPA - 객체와 테이블 매핑, DB 스키마 자동 생성 (0) | 2022.06.24 |
JPA - 영속성 컨텍스트 (0) | 2022.06.23 |
JPA - 세팅, JPA&JPQL 개요 (0) | 2022.06.21 |
Comments