Free Lines Arrow
본문 바로가기
DataBase/JPA

[JPA] 영속성 컨텍스트

by skahn1215 2021. 7. 30.
728x90
반응형

영속성 컨텍스트란?

  • 영속성 컨텍스트에 대해 알아본다.
  • 동작을 알아본다.

 

 

 

영속성 컨텍스트

  • JPA 를 이해하는데 기본이 된다.
  • 논리적인 개념이다.
  • 엔티티를 영구저장하는 환경
  • EntityManager.persist(entity)
    - 엔티티 매니저를 통해 영속성 컨텍스트에 접근한다.

 

 

 

 

엔티티 매니저를 통해 어떻게 접근하고 관리가 될까?

 

엔티티 매니저 팩토리와 엔티티 

  • EntityManagerFactory 는 웹에서 하나로만 생성하여 사용한다.
  • EntityManager는 사용자의 요청마다 생성해서 사용한다.
  • EntityManager는 내부적으로 DB 커넥션을 사용해 DB와 연결한다.

 

 

 

 

 

엔티티의 생명주기

EntityManager가 엔티티를 관리 하는 부분에서 엔티티의 생명주기 또한 중요하다.

 

 

 

  • 비영속(new/transient)
    영속성 컨텍스트와 전혀 관계가 없는 새로운 상태

  • 영속(managed)
    영속성 컨테스트에 관리 되는 상태

  • 준영속(detached)
    영속성 컨텍스트에 저장되었다가 분리된 상태

  • 삭제(remove)
    삭제된 상태

 

 

 

 

비영속

  • 비영속은 JPA 즉 EntityManager 가 관리하지 않는 상태이다.
  • 새로운 객체를 만들었을때 보통 비영속이다.

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

 

 

 

영속

  • 영속은 EntityManager 가 관리하는 상태이다.
  • 객체를 em.persist(member); 영속성 컨텍스트에 넘겨주면 된다.

//객체를 생성한 상태(비영속) 
Member member = new Member(); 
member.setId("member1"); 
member.setUsername(“회원1”);
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
//객체를 저장한 상태(영속)
em.persist(member);

 

 

 

준영속, 삭제

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


//객체를 삭제한 상태(삭제) 
em.remove(member);

 

 

 

 

영속성 컨텍스트의 이점

영속성 컨텍스트는 다음과 같은 이점들이 있다.

  • 1차캐시
  • 동일성보장
  • 트랜잭션을 지원하는 쓰기지연
  • 변경감지
  • 지연로딩

 

 

 

 

 

1차캐시

  • DB에 저장하기 전 영속성된 객체들을 저장하고 있는 캐시이다.
  • 코드로 보면 setUsername 까지는 1차캐시에는 아무런 데이터가 없다.
  • 사용자가 persist 로 객체를 넘겨주면 그때 부터 1 차캐시에 id 와 객체의 데이터가 저장된다.

 

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

// 1차 캐시에 객체정보가 저장됨
//엔티티를 영속
em.persist(member);

 

 

 

 

 

 

조회시 동작구조

  • 1차 캐시에 저장후 조회를 하는경우
  • 찾기위한 쿼리문은 수행되지 않는다.
    - 1차 캐시에서 먼저 찾고 없으면 DB 에서 조회 하기 때문이다.
  • persist 로 객체정보를 영속 컨텍스트에 저장
  • 조회시 캐시에서 조회

 

캐시에서 조회

Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
//1차 캐시에 저장됨
em.persist(member);
//1차 캐시에서 조회
Member findMember = em.find(Member.class, "member1");

 

 

 

DB에서 조회

  • 영속성 컨텍스트에 해당 id 를 가진 객체가 없다면 DB 에서 조회한다.
  • 조회한 객체를 영속성 컨텍스트에 저장한다.
Member findMember2 = em.find(Member.class, "member2");

 

 

 

 

 

동일성 보장

  • 동일한 트랜잭션 안에서 JPA 는 동일성을 보장해준다.
  • 즉 다음과 같은 코드로 비교가 가능하다는 것이다.
Member findMember2 = em.find(Member.class, 101L);
Member findMember3 = em.find(Member.class, 101L);
if (findMember2 == findMember3) {
    System.out.println("findMember2 == findMember3");
}

 

 

 

 

 

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

쉽게 설명하면 버퍼에 데이터를 가지고 있다가 한번에 DB에 저장하는 개념이라고 생각하면

쉬울것 같다.

 

 

  • persist를 쓴다고 바로 DB에 저장되는 것이 아니다.
    - 일단 영속성 컨텍스트에 객체 정보를 담아둔다.
  • EntityTeansaction 에서 commit 함수를 호출해 주면 그때 DB에 쿼리가 날라간다.

 

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();

//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
transaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);

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

 

 

 

Commit

  • 커밋이 되면 flus가 호출되고 DB에 sql 문을 날린다.
  • 실제 DB 에서 commit을 한다
  •  <property name="hibernate.jdbc.batch_size" value="10"/>  속성으로 얼마나 모았다가 
    DB에 저장할지 정할수 있다.

 

 

 

 

변경감지

  • 영속성으로 객체가 관리 될때 멤버의 속성이 변경 되었다
  • commit  되는 시점에 EntityManager 가 엔티티와 스냅샷을 비교한다.
  • 스냅샷은 최초로 읽어온 시점의 상태를 저장하고 있다.
  • 변경을 확인후 update 쿼리를 수행한다.
  • 코드를 보면 따로 update를 하는 함수가 없다.
    - 자동으로 업데이트가 되기 때문이다.

 

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(); // [트랜잭션] 커밋

 

 

 

 

참고: https://www.inflearn.com/course/ORM-JPA-Basic/lecture/21687?speed=1&tab=curriculum 

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 학습 페이지

지식을 나누면 반드시 나에게 돌아옵니다. 인프런을 통해 나의 지식에 가치를 부여하세요....

www.inflearn.com

 

728x90
반응형

'DataBase > JPA' 카테고리의 다른 글

[JPA] 준영속성  (0) 2021.07.30
[JPA] 플러시  (0) 2021.07.30
[JPA] JPA CRUD 기본  (0) 2021.07.30
[JPA] JPA 환경설정  (0) 2021.07.29
[JPA] JPA 란?  (0) 2021.07.28

댓글