본문 바로가기

JPA

[JPA] JPA - 영속성 관리

 

해당 내용은 인프런 - 자바 ORM 표준 JPA 프로그래밍 - 기본 편에서 공부한 내용을 정리한 것입니다.

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., 본 강의는 자바 백엔

www.inflearn.com

JPA에서 가장 중요한 2가지
1. 객체와 관계형 데이터베이스를 어떻게 매핑할 것인가? 매핑의 관점 (설계)
2. 영속성 컨텍스트 (실제로 JPA가 내부에서 어떻게 동작하는가)

엔티티 매니저 팩토리(EntityManager Factory)와 엔티티 매니저(EntityManager)

엔티티 매니저 팩토리를 통해서 고객의 요청이 올 때마다 엔티티 매니저를 만든다.
엔티티 매니저는 내부적으로 데이터베이스 커넥션을 사용해서 DB를 이용하게 된다.

영속성 컨텍스트란?

  • JPA를 이해하는데 가장 중요한 용어
  • 엔티티를 영구저장하는 환경이라는 뜻
  • EntityManager.persist(entity); => DB에 저장하는 것이 아닌 엔티티를 영속성 콘텍스트에 저장한다는 것


엔티티의 생명주기

  1. 비영속 (new / transient)
    • 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
    • //객체를 생성한 상태(비영속)
      Member member = new Member();
      member.setId("member");
      member.setUsername("회원");
  2. 영속(managed)
    • 영속성 컨텍스트에 관리되는 상태
    • 1차 캐시에 올리는 것도 영속 상태라고 한다. 
    • 영속 상태가 된다고 해서 DB에 쿼리가 실행되는 것이 아니다. 
    • EntityManager em = emf.createEntityManager(); 
      em.getTransaction().begin(); 
      
      //객체를 저장한 상태(영속) 
      em.persist(member);
       
  3. 준영속(detached)
    • 영속성 컨텍스트에 저장되었다가 분리된 상태
    • //회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태가 된다.
      em.detach(member);​
  4.  삭제(removed)
    • 객체를 삭제한 상태(삭제)
      em.remove(member);

영속성 컨텍스트의 이점

  1. 1차 캐시 조회
  2. 동일성 보장
    • Member a = em.find(Member.class , "member"); 
      Member b = em.find(Member.class , "member"); 
      
      System.out.println(a == b); //동일성 비교 true
      1차 캐시로 반복 가능한 읽기(Repeatable Read) 등급의 트랜잭션 격리 수준을 
      데이터베이스가 아닌 애플리케이션 차원에서 지원
  3. 트랜잭션을 지원하는 쓰기 지연
    • Member member1 = new Member(150L, "A");
      Member member2 = new Member(160L, "B");
      
      em.persist(member1); 
      em.persist(member2); 
      
      tx.commit();​
       
    • 커밋이 될 때 쿼리가 날아간다. 버퍼링이라는 기능
    • em.persist 할 때마다 쿼리가 날아간다면 최적화할 수 있는 여지가 없다.
    • 그런데 batch size를 통해서 설정된 갯수만큼의 쿼리를 한 번의 네트워크 연결로 쿼리를 보내 commit 한다.
  4. 변경 감지
    • member.setName("zzzzz");
    • em.persist(member) => 할 필요 없음
  5. 지연 로딩

플러시(flush)
1. 영속성 컨텍스트를 비우지 않음 
2. 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화 
3. 트랜잭션이라는 작업 단위가 중요 -> 커밋 직전에만 동기화하면 됨 


영속성 컨텍스트의 변경내용을 데이터베이스에 반영 // COMMIT이 되는 건 아님

플러시가 발생하면 무슨 일이 생기는가?
1.변경 감지 (Dirty Checking)
2. 수정된 엔티티 쓰기 지연 SQL 저장소에 등록
3. 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송 (등록, 수정, 삭제 쿼리)

영속성 콘텍스트를 플러시 하는 방법
1.em.flush() - 직접 호출 
2. 트랜잭션 커밋 - 플러시 자동 호출
3.JPQL 쿼리 실행 - 플러시 자동 호출

주의 : 플러시를 한다고 해서 1차 캐시의 내용이 지워지지 않는다.

플러시 모드 옵션


FlushModeType.AUTO

  • 커밋이나 쿼리를 실행할 때 플러시 (기본값)
  • 웬만하면 수정하지 않고 사용한다고 한다.

FlushModeType.COMMIT

  • 커밋할 때만 플러시

준영속 상태

  • 영속상태에서 준영속 상태로 변경
  • 영속 상태의 엔티티가 영속성 콘텍스트에서 분리(detached)
  • 영속성 컨텍스트가 제공하는 기능을 사용 못함

준영속 상태로 만드는 방법
1.em.detach(entity)

  • 특정 엔티티만 준영속 상태로 전환

2.em.clear()

  • 영속성 컨텍스트를 완전히 초기화

3.em.close()

  • 영속성 컨텍스트를 종료

'JPA' 카테고리의 다른 글

[JPA] JPA - 엔티티 매핑  (0) 2021.08.01