- 참조: 자바 ORM 표준 JPA 프로그래밍
- 플러시
플러시(flush())는 영속성 컨텍스트의 변경 내용을 DB에 반영하는 연산이다. 플러시를 수행하면
- 변경 감지 -> 영속성 컨텍스트의 엔티티와 스냅샷 비교 -> 수정된 엔티티 수정 쿼리 생성 -> 쓰기 지연 SQL 저장소 등록
- 쓰기 지연 SQL 저장소 -> DB 로 쿼리 전송
영속성 컨텍스트의 플러시는 3 가지 방법으로 수행할 수 있다.
- em.flush()로 직접 호출
- 트랜잭션 커밋시 자동 호출
- JPQL 쿼리 실행 시 자동 호출
em.flush() 를 직접 호출하면 영속성 컨텍스트를 강제로 플러시한다. 하지만 이는 거의 사용하지 않는 기능이다.
트랜잭션 커밋시 자동 호출되어야 하는 이유는 flush() 와 COMMIT 이 다르기 때문이다. flush() 는 우리가 DB Editor 에서 SQL 을 작성하는것이라고 할 수 있으며, 트랜잭션 커밋은 말 그대로 COMMIT 을 수행하는것이다. SQL을 쓰지 않고 COMMIT을 수행한다면 당연히 어떤 일도 일어나지 않는다. 트랜잭션 커밋시 flush() 가 자동호출 되는 이유가 바로 이 때문이다.
JPQL 이나 Criteria 쿼리 실행시에도 플러시가 자동 호출되는데 예제코드를 하나 보자.
Member member1 = new Member();
member1.setId("ID#1");
member1.setUserName("ocwokocw1");
member1.setAge(31);
em.persist(member1);
Member member2 = new Member();
member2.setId("ID#2");
member2.setUserName("ocwokocw2");
member2.setAge(32);
em.persist(member2);
Member member3 = new Member();
member3.setId("ID#3");
member3.setUserName("ocwokocw3");
member3.setAge(33);
em.persist(member3);
List<Member> members = em.createQuery("select m from Member m", Member.class)
.getResultList();
System.out.println("members size: " + members.size());
System.out.println("flush test");
위의 코드에서 member1,2,3 을 영속화 시키면 아직 영속성 컨텍스트에만 있고 DB 에는 반영이 되지 않은 상태이다. 그런데 이때 JPQL 로 DB 에서 조회하면 member1,2,3 은 조회되지 않는다. 이런 문제를 예방하기 위해 JPA 에서는 JPQL 을 실행할 때 플러시를 호출한다. (find() 연산은 호출하지 않는다.)
위의 코드에서 System.out.println("flush test") 부분에 디버깅을 걸어놓고 코드를 수행해보면 commit 이 되지 않아도 아래 실행결과가 나타나는것을 알 수 있다.
Hibernate:
/* insert com.example.demo.member.Member
*/ insert
into
MEMBER
(age, NAME, ID)
values
(?, ?, ?)
Hibernate:
/* insert com.example.demo.member.Member
*/ insert
into
MEMBER
(age, NAME, ID)
values
(?, ?, ?)
Hibernate:
/* insert com.example.demo.member.Member
*/ insert
into
MEMBER
(age, NAME, ID)
values
(?, ?, ?)
Hibernate:
/* select
m
from
Member m */ select
member0_.ID as id1_0_,
member0_.age as age2_0_,
member0_.NAME as name3_0_
from
MEMBER member0_
members size: 3
- 플러시 옵션
엔티티 매니저의 플러시 모드를 변경할 수 있다. javax.persistence.FlushModeType 을 사용하면 된다. AUTO 와 COMMIT 이 있으며 AUTO는 커밋이나 쿼리 실행할 때 플러시를 하고, COMMIT 은 커밋할때만 플러시를 한다. 기본값은 AUTO 이다.
플러시 옵션은 성능 최적화를 위해 사용하는 경우가 있으며 이는 나중에 살펴보기로 한다. 또 한 가지 주의사항이 있는데 플러시는 영속성 컨텍스트에 보관된 엔티티를 DB에 동기화하는것이지 지우는것은 아니다.
'Framework and Tool > JPA' 카테고리의 다른 글
JPA - 엔티티 맵핑 - 기본 (0) | 2021.06.27 |
---|---|
JPA - 영속성 관리 - 준영속과 병합 (0) | 2021.06.24 |
JPA - 영속성 관리 - 영속성 컨텍스트 (0) | 2021.06.24 |
JPA - 영속성 관리 - 엔티티의 생명주기 (0) | 2021.06.23 |
JPA - 엔티티 매니저, 트랜잭션, JPQL (0) | 2021.06.23 |
댓글