ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JPA] 영속성 컨텍스트란? (개념, 장점)
    JAVA/JPA 2021. 4. 23. 11:30

    김영한님의 JPA 책 중 앞부분 내용인 영속성에 관련한 부분을 글로 설렁설렁 읽고 맵핑 관련된 부분만 읽은 뒤

    바로 실천에 옮겨봤다.

    이미 ERD를 다 완성시키고 양방향 맵핑을 한 뒤 책을 다시 읽어보니, [단방향 맵핑위주로 하고 그 뒤로 필요한부분만

    양방향 맵핑을 하는게 좋다]고 되어 있었다...

     

    데이터베이스 테이블의 관계를 통해 테스트코드나 조회, 수정 등 과정을 하고싶다면 먼저 영속성 컨택스트가 뭔지

    혹은 어떻게 동작하는 지 미리 숙지하면 좋을 것 같다.

     

    꼼꼼하게 책을 읽지 않은 덕분일 수 있겠지만, 양방향 맵핑을 하면서 생기게 된 문제점들과 영속성 컨택스트에 관한 내용을

    덕분에 다시 한 번 읽고 블로그에 포스팅 하는 계기가 될 수 있었던 것 같다..

    도서관에서 빌렸던 책이라 밑줄과 메모를 하지 못했던 것이 불편해 결국 책을 샀다.

     

    웬만하면 관련 서적은 친구를 통하거나 다른 블로그들을 보면서 참고하거나 했지만 JPA 만큼은 제대로 공부하고 싶었고,

    공부를 하면서 되게 신기하고 재밌는것 같다.

     

    JPA를 기본적인 CRUD 구현만해서 쓰니깐 신기하고 왜 이렇게 쉬울까? 생각이 들었다.

    러닝커브가 높다고 말했지만, 잘 모르겠다는 생각이 드는 와중에 문제가 생겼다.

    테스트 코드 작성 중 여러 오류가 떴고, 어떤 문제인지도 몰랐다. 그 순간 내가 너무 안일하게 생각했고,

    다시 한번 책을 잡고 정독해봤다.

    며칠동안 고민했던 테스트코드 오류를 해결할 수 있었고, 포스팅을 통해 개념을 다시 잡을 수 있었다.

     

    1. 영속성 컨텍스트

    먼저 영속성 컨택스트를 공부하기 이전에 Entity manager FactoryEntity manager를 알아야 한다.

    말 그대로 번역해보면 Entity manager Factory(엔티티 매니저 팩토리)Entity manager을 마구 찍어내는 공장과 같다.

     

    그렇다면, Entity manager란 뭘까?

    간단하게 말해서 Entity manager를 가상의 데이터 베이스를 관리해주는 즉, Entity를 관리해주는 것으로 보면 될 것 같다.

    ( 앞으로 설명에서 em은 Entity manager 변수라 생각하면된다. )

    김영한님의 자바 ORM 표준 JPA 프로그래밍 책 (내용) 

    JPA에서는 EntityManager를 사용해 CRUD를 구현한다.

    Entity manager는 트랜잭션이 시작되면 DB와 커넥션이 형성되며 그 전까지는 형성되지 않는다.

     

    Entity Factory, Entity manager에서 스레드와 관련된 얘기도 있었지만, 정확히 알 지 모르기 때문에 다음에 포스팅을 하겠다.

     

    Entity의 생명주기에는 총 4가지가 있다.

    1. 비영속 : 영속성 컨텍스트와 전혀 관계가 없는 상태  ex) em.persist() 호출하기 전

    2. 영속 : 영속성 컨텍스트에 저장된 상태 즉, 영속성 컨택스트가 관리하는 상태

    3. 준영속 : 영속성 상태에 저장되었다 불리된 상태

    4. 삭제 : 삭제된 상태

     

    자 그럼 영속성 컨텍스트(Persistence Context)를 알아보자.

     

    영속성 컨텍스트란?  "Entity를 영구 저장하는 환경" 이다.  논리적인 개념에 가깝다.

     

    Entity manager영속성 컨텍스트에 Entity를 보관하고 관리 한다.

     

    em.persist(Entity) 의 진정한 의미는 Entity manager를 이용하여 영속성 컨텍스트에 저장하는 것이다.

    영속상태의 Entity는 식별자 값이 반드시 있어야하며, 영속성 컨텍스트는 Entity를 식별자 값으로 구분한다.

     

    영속성 컨택스트와 데이터베이스 저장 (중요!!)

     

    JPA는 보통 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 Entity를 DB에 반영한다.

    커밋을 하게되면 자동으로 앞서 em.flush()가 작동된다.

     

    트랜잭션 커밋 이란 뭘까???

    김영한님의 자바 ORM 표준 JPA 프로그래밍 책 (내용) 

    다음이 트랜잭션의 커밋이다. (flush + commit)

    1. em.flush()는 쓰기 지연 SQL에 있는 쿼리들을 DB에 적용시키는 과정이다.

    2. commit()을 한다. 이때 커밋하지 않는다면 DB에 반영되지 않는다.

     

    위 그림을 봤을 때 1차 캐시와 쓰기지연 SQL 저장소가 있다.

     

    먼저 영속성 컨텍스트가 가지는 장점에 대해 말하겠다.

    1. 1차 캐시

    2. 동일성 보장

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

    4. 변경감지 (dirty checking)

    5. 지연로딩

     

    - 1차 캐시

    영속성 컨텍스트는 내부에 캐시를 가진다. 영속상태의 Entity는 모두 이곳에 저장한다.

    장점: 영속성 컨텍스트 내부에 저장된 Entity를 find할 때 쿼리를 날릴 필요가 없다.

    만약 캐시에 없다면 DB조회하여 1차 캐시에 로드한 뒤 정보를 전송해준다.

     

    김영한님의 자바 ORM 표준 JPA 프로그래밍 책 (내용) 

     

    - 동일성 보장

    영속성 컨텍스트 내부 Entity를 find해서 비교해 본다면 똑같은 객체이다.

     

    동등성: 같은 객체 일 수 있고 아닐 수 있다. 같은 값을 가지는 것!! 개념 주의

     

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

    1차 캐시에 Entity를 persist하거나 수정할 때 쓰기지연 저장소에 SQL을 만든다.

    쓰기 지연 저장소에 SQL을 모아놓은 뒤, flush()와 commit()을 통해 DB에 반영한다.

    장점: 쿼리를 일일히 날리지 않으면서 효율성을 확보할 수 있다.

    update 쿼리 반영 시 실제로 마지막에 Entity와 비교했을 때 수정된 것만 반영 시킬 수 있다.

     

    - 변경감지 (dirty checking)

    Entity의 변경 사항을 DB에 자동으로 반영되게 하는 것.

    JPA는 Entity를 영속성 컨텍스트에 보관할 때 최초 상태를 복사해서 저장 한다. (이를 '스냅샷' 이라 한다.)

    flush() 시점에 스냅샷과 Entity를 비교하여 쿼리문을 작성한다.

    JPA의 기본전략은 모든 내용을 Update하는 것이다. (데이터 전송량이 많다면 단점) -> Hibernate로 보완가능.

     

    - 지연로딩

    나중에 지연로딩 관련해서 포스팅 할 예정이다. 지연로딩은 해당 데이터가 필요할 때 DB에서 조회를 통해 가져오는 것이다.

    DB에 관계가 형성되면 관련된 테이블의 정보를 들고 와야할 때가 있다.

    이때 한번에 가져오는 Eager와 해당 데이터를 실제로 사용할 때 가져오는 Lazy 방법이 있다.

     

    기본적인 JPA가 돌아가는 틀은 맞춰진 듯 하다. 영속성 개념을 이해하고나니 JPA 인터페이스 자체를 읽을 때

    훨씬 편하고 save()와 saveAndFlush()의 동작방식을 확실히 알 수 있었다.

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

    [JPA] 테이블 1:N 관계 만들기 (ERD 연습 1)  (0) 2021.04.14

    댓글

Designed by Tistory.