Contents

[자바 ORM 표준 JPA 프로그래밍] 3장 영속성 관리 - 플러시, 준영속

자바 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) 된 것을 준영속 상태라고 한다.
  • 준영속 상태의 엔티티는 영속성 컨텍스트가 제공하는 기능을 사용할 수 없다.
  • 개발자가 직접 준영속 상태로 만드는 일은 드물다.

준영속 상태를 만드는방법

  1. em.detach(엔티티) : 특정 엔티티만 준영속 상태로 전환
  2. em.clear() : 영속성 컨텍스트를 완전히 초기화
  3. 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();