프로그래밍/Java

[JPA] 영속성 관리

southouse 2021. 8. 25. 11:13
728x90

Entity 란?

  • DB 테이블에 매핑되는 자바 클래스

영속성 컨텍스트 (Persistence Context)

  • Entity를 영구히 저장하는 환경
  • Entity Manager → Persistence Context → Database 순으로 접근
    • 1차 캐시
      • 만약, find() 메소드를 호출했을 때, 영속성 컨텍스트의 1차 캐시에서 찾고 없으면 데이터베이스에서 조회한다.
      • 캐시로 성능 상의 이점을 누릴 수 있음.
    • 동일성 보장
      • 영속성 컨텍스트에서 관리하는 엔티티 객체는 동일성을 보장해준다.
    • 트랜잭션을 지원하는 쓰기 지연
    • 변경 감지
    • 지연 로딩

Entity Lifecycle

  • 비영속
    • 객체 생성한 직후, 영속성 컨텍스트와는 관계가 전혀 없음.
  • 영속
    • persist()find() 메소드를 통해 엔티티를 저장하거나 조회하면 영속 상태 (=엔티티가 영속성 컨텍스트에 저장되고, 엔티티 매니저에 의해 관리된다)
  • 준영속
    • detach() 메소드로 준영속 상태로 전환 가능
    • 전환 시에 1차 캐시, 쓰기지연 저장소에 저장된 정보들이 모두 삭제 됨

행위 (Behavior)

  • 조회 → find()
    • 영속성 컨텍스트를 거쳐서 조회한다.
  • 등록 → persist()
    • 메소드를 실행하면, 쓰기지연 SQL 저장소에 insert쿼리를 등록하고, 영속성 컨텍스트에 저장한다.
      • 쓰기지연을 수행하는 이유는, 네트워크 통신 횟수를 줄여 이득을 취하기 위함.
    • 마지막 flush 동작 이후에 데이터베이스로 쿼리를 보낸다.
      • flush란, 트랜잭션이 끝나는 시점에 정보들을 종합하여 최종 SQL을 날리는 행위 또는 명령
  • 수정
    • JPA에 변경감지라는 기능이 있어 딱히 메소드가 존재하지 않는다.
    • 엔티티가 영속상태에 들어가면, 스냅샷을 찍어두어 flush가 일어날 때 영속성 컨텍스트에 저장된 엔티티의 속성 값과 엔티티 스냅샷의 속성 값을 비교하여 변경된 부분을 감지해서 변경한다. → dirty check가 따로 필요 없음.
    • 실제 update 이벤트가 발생하면 전체 속성에 대한 업데이트를 실행하는 쿼리가 생성된다.
      • @DynamicUpdate라는 어노테이션으로 수정된 데이터에 대해서만 update를 할 수 있다.
  • 삭제 → remove()
    • 데이터를 준영속 상태로 바꾸는 detach() 메소드와 데이터베이스에서 데이터를 삭제하는 delete 이벤트가 합쳐진 것
  • 병합 → merge()
    • 데이터를 준영속 상태에서 영속 상태로 만드는 행위
    • 해당 엔티티가 영속화될 수 있는지(실재 존재하는지) 체크하기 위해 조회 이벤트를 날리게 된다.
    • JPA 명세에서는 해당 엔티티를 찾을 수 없을 경우 IllegalArgumentException이 발생하게 됨
      • hibernete에서는 그냥 새로 저장해주고, 영속성 컨텍스트에 등록하여 리턴
  • 반영 → flush()
    • 영속성 컨텍스트의 변경 내용을 데이터베이스에 최종적으로 반영하는 행위 (commit과는 다름)
    • 발생시키는 방법
      • 직접 호출 → em.flush()
      • 트랜잭션 commit시에 자동 호출
      • JPQL 실행 시 자동 호출
  • flush 모드 → javax.persistence.FlushModeType
    • FlushModeType.AUTO - commit이나 쿼리를 실행할 때 flush
    • FlushModeType.COMMIT - commit할 때만 flus

Reference

300x250