JPA1

김영환·2023년 10월 10일
0

JPA

목록 보기
2/4

영속성 관리 - JPA 내부구조

1. 영속성 컨텍스트
JPA를 이해하는데 가장 중요한 용어로 엔티티를 저장하는 환경이라는 뜻이다.
애플리케이션과 데이터베이스 사이에서 객체를 보관하는 가상의 데이터베이스 같은 역할을 한다.
엔티티 매니저를 통해 영속성 컨텍스트에 접근할 수 있고, 엔티티 매니저를 생성할 때 영속성 컨텍스트도 하나 만들어진다(1:1)

EntityManager.persist(대상객체);

이 코드를 보면 "대상객체"에 들어가는 객체(Team, Member..) 등을 DB에 저장하는구나... 싶지만, 좀 더 깊은 의미가 있다.
객체를 DB에 바로 저장하는 것이 아니라 영속성 컨텍스트라는 곳에 일단 저장을 한다.

엔티티의 생명주기

  • 비영속(new/transient) -> 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
  • 영속(managed) -> 영속성 컨텍스트에 관리되는 상태
  • 준영속(detached) -> 영속성 컨테스트에 저장되었다가 분리된 상태
  • 삭제(remove) ->삭제된 상태

비영속 - JPA와 전혀 상관 없는 상태로 엔티티 객체를 생성했지만 아직 영속성 컨텍스트에 저장하지 않은 상태를 말한다.

Member member = new Memer();
member.setId("member1");
member.setUsername("회원1");

영속 - JPA에 속해있는 상태로 영속성 컨텍스트에 저장한 상태를 말하며, 영속성 컨텍스트에 의해 관리된다

em.persist(member)

준영속 - 엔티티를 영속성 컨텍스트에서 분리 (영속상태X)

em.detach(member);	// 특정 엔티티만 준영속 상태로 전환
em.clear();			// 영속성 컨텍스트를 완전히 종료
em.close();			// 영속성 컨텍스트를 종료

삭제 - 엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제한다.

em.remove(member);

영속성 컨텍스트의 이점

  • 1차캐시
  • 동일성(identity)보장
  • 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)
  • 변경감지(Dirty Checking)
  • 지연 로딩(Lazy Loading)

1차캐시 - 엔티티 조회

  • 영속성 컨텍스트와 식별자 값
    -> 엔티티를 시별자 값(@id로 테이블의 기본 키와 매핑)으로 구분
    -> 영속 상태는 식별자 값이 반드시 있어야 한다.
    -> 식별자 값이 없으면 예외 상황
  • 영속성 컨텍스트와 데이터베이스 저장
    -> JPA는 보통 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 데이터베이스에 반영
    -> 플러시(flush)
  • 엔티티 등록 - 트랜잭션을 지원하는 쓰기 지연
EntityManager em = emf.createEntityManager();
 EntityTransaction ts = em.getTransaction();
 ts.begin();	// 트랜잭션 시작
 em.persist(memberA);
 em.persist(memberB);
 // 여기까지 Insert SQL을 데이터베이스에 보내지 않는다.
 // 커밋하는 순간 데이터베이스에 Insert SQL을 보낸다
 ts.commit();	// 트랜잭션 종료(커밋)

  • 엔티티 수정 - 변경감지(Dirty Checking)
EntityManager em = emf.createEntityManager();
 EntityTransaction ts = em.getTransaction();
 ts.begin();	// 트랜잭션 시작
 // 영속 엔티티 조회
 Member memberA = em.find(Member.class, "memberA");
 // 영속 엔티티 데이터 수정
 memberA.setUsername("admin");
 memberA.setAge(20);
 // em.update(MemberA); 이런 코드가 있어야하지 않을까(x)
 ts.commit();	// 트랜잭션 종료(커밋)

-> flush가 호출되는 시점에 Entity와 스냅샷을 전부 전부 비교 후 (최적화 알고리즘으로 진행) 변경이 된 것을 감시(Dirty Checking)한 후에 update 쿼리를 작성 후, update 쿼리를 날린다.

엔티티 삭제

// 삭제 대상 엔티티 조회
 Member memberA = em.fid(Memer.class, "memberA");
 em.remove(memberA);
profile
개발

0개의 댓글