자바 ORM 표준 JPA 프로그래밍 학습 내용 정리한 포스팅 입니다.
3.5 플러시
- 플러시(
flush()
) 는 영속성 컨텍스트의 내용을 데이터베이스에 반영한다.
- 영속성 컨텍스트의 변경 내용을 데이터베이스와 동기화 하는 것이 플러시이다.
플러시를 실행하면
- 변경 감지가 동작하여 영속성 컨텍스트에 있는 모든 엔티티를 스냅샷과 비교해서 수정된 엔티티를 찾는다. => 수전된 엔티티는 수정 쿼리를 만들어 쓰기지연 SQL 저장소에 등록
- 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송한다.
플러시 방법
- em.flush()
- 트랜잭션 커밋 시 플러시 자동 호출 : JPA는 트랜잭션을 커밋할 때 플러시를 자동으로 호출한다.
- JPQL 쿼리 실행시 플러시 자동 호출
- JPQL이나 Criteria 같은 객체 지향 쿼리를 통하여 실행할때 플러시를 자동으로 호출한다.
- 식별자를 기준으로 조회하는
find()
메소드를 호출할 때는 플러시가 실행되지 않는다.
1
2
3
4
5
6
7
8
9
|
// JPQL 시 자동 플러시
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
// 중간에 JPQL 실행
// 조회시 memberA, memberB, memberC 도 쿼리결과에 포함된다.
query = em.createQuery(" SELECT m FROM Member m ", Member.class);
List<Member> members = query.getResultList();
|
플러시 모드 옵션
- javax.persistence.FlushModeType 사용
- **FlushModeType.AUTO **: 커밋이나 쿼리를 실행할 때 플러시값 (별도로 지정하지않으면 기본값)
- **FlushModeType.COMMIT **: 커밋할때만 플러시
1
|
em.setFlushMode(FlushModeType.COMMIT); // 플러시모드 직접 설정
|
3.6 준영속
- 영속성 컨텍스트가 관리하는 영속 상태의 엔티티가 영속성 컨텍스트에서 분리(
detached
) 된 것을 준영속 상태라고 한다.
- 준영속 상태의 엔티티는 영속성 컨텍스트가 제공하는 기능을 사용할 수 없다.
- 개발자가 직접 준영속 상태로 만드는 일은 드물다.
준영속 상태를 만드는방법
em.detach(엔티티)
: 특정 엔티티만 준영속 상태로 전환
em.clear()
: 영속성 컨텍스트를 완전히 초기화
em.close()
: 영속성 컨텍스트를 종료
엔티티를 준영속 상태로 전환 : detach()
- 1차 캐시부터 쓰기 지연 SQL 저장소 까지 해당 엔티티를 관리하기 위한 모든 정보가 제거
영속성 컨텍스트 초기화 : clear()
- 영속성 컨텍스트의 모든 것이 초기화 되버린다. 영속성 컨텍스트를 제거하고 새로 만든 것과 같다.
영속성 컨텍스트 종료 : clese()
준영속 상태의 특징
- 거의 비영속 상태에 가깝다. : 1차캐시, 쓰기지연, 변경감지, 지연로딩을 포함한 영속성 컨텍스트의 기능이 동작하지 않는다.
- 식별자 값을 가지고 있다. : 준영속 상태에서는 이미 한 번 영속 상태였으므로 식별자 값을 가지고 있다.
- 지연 로딩을 할 수 없다.
merge()
- 준영속 상태의 엔티티를 다시 영속 상태로 변경 할 때 사용한다.
- 병합은 파라미터로 넘어온 엔티티의 식별자 값으로 영속성 컨텍스트를 조회하고 찾는 엔티티가 없으면 데이터베이스를 조회하며, 데이터베이스에도 조회하지 못하면 새로운 엔티티를 생성해 병합한다.
- 병합은 준영속, 비영속을 신경 쓰지 않는다.
- 병합은
save or update
의 기능을 수행한다.
준영속 병합
비영속 병합
- 병합은 비영속 엔티티도 영속상태로 만들 수 있다.
1
2
3
4
|
Member member = new Member();
Member newMember = em.merge(member);
tx.commit();
|