[JPA] 영속성 관리

mminjg·2022년 7월 11일
0

jpa

목록 보기
1/1

영속성 컨텍스트

영속성 컨텍스트란 "엔티티를 영구 저장하는 환경"이라는 뜻이다.
엔티티 매니저를 통해 영속성 컨텍스트에 접근한다.

엔티티의 생명주기

// 객체를 생성한 상태 (비영속)
Member member = new Member();
Member.setId("member1");
member.setUserName("회원1");

// 객체를 저장한 상태(영속)
em.persist(member);

// 객체를 가져온 상태(영속)
Member findMember = em.find(Member.class, "member1");

// 회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태
em.detach(member);

//객체를 삭제한 상태(삭제)
em.remove(member);
  • 비영속 (new/transient)
    영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
  • 영속 (managed)
    영속성 컨텍스트에 관리되는 상태
  • 준영속 (detached)
    영속성 컨텍스트에 저장되었다가 분리된 상태
  • 삭제 (removed)
    삭제된 상태

영속성 컨텍스트의 이점

1차 캐시

DB를 조회하지 않고 1차 캐시에서 조회한다.
(1차 캐시에 없는 경우 DB조회 및 1차캐시에 저장)

동일성 보장

Member a = em.find(Member.class, "member1"); 
Member b = em.find(Member.class, "member1");
    
System.out.println(a == b); //동일성 비교 true

트랜잭션을 지원하는 쓰기 지연

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
transaction.begin(); // [트랜잭션] 시작

 em.persist(memberA);
 em.persist(memberB);
 //여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.

 //커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
 transaction.commit(); // [트랜잭션] 커밋

변경 감지(Dirty Checking)

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // [트랜잭션] 시작

// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");

// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);

transaction.commit(); // [트랜잭션] 커밋
  1. 커밋 flush
  2. 엔티티와 스냅샷 비교
  3. UPDATE SQL 생성
  4. flush
  5. commit

플러시

  • 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영(동기화)한다.
  • 영속성 컨텍스트를 비우지 않는다.

지연 로딩(Lazy Loading)

  • 지연 로딩: 객체가 실제 사용될 때 로딩
    • 멤버 객체의 팀의 속성을 가져올 때 로딩
  • 즉시 로딩: JOIN SQL로 한번에 연관된 객체까지 미리 조회
    • 한꺼번에 조인해서 가져옴
//지연로딩
Member member = memberDAO.find(memberId);  --> SELECT * FROM MEMBER
Team team = member.getTeam();
String teamName = team.getName();          --> SELECT * FROM TEAM

//즉시로딩
Member member = memberDAO.find(memberId);  --> SELECT * M.*, T.*
Team team = member.getTeam();                  FROM MEMBER
String teamName = team.getName();              JOIN TEAM ...

0개의 댓글