본문 바로가기
내일배움캠프(Sparta)/Spring

[Spring] Entity / Persistence Context / Transaction

by mmm- 2023. 11. 7.

1) Entity

: JPA에서 관리되는 클래스. 즉, 객체를 의미

  • Entity 클래스는 DB의 테이블과 매핑되어 JPA에 의해 관리됨.

 

Annotation

@Entity

: JPA가 관리할 수 있는 Entity 클래스로 지정하는 annotaion

 

@Table

:  매핑할 테이블 지정

 

@Id

: table의 기본키를 지정해주는 annotation

  • 영속성 컨텍스트에서 entity를 구분할 때 사용
  • 기본키를 넣어주지 않으면 오류 발생

@GeneratedValue

: 기본 키 생성을 DB에 위임 가능

  • (strategy = GenerationType.IDENTITY)
    : DB가 자동으로 ID를 생성하도록 함

@Column

  • nullable
    : null 허용 여부 (default : true)
  • unique
    : 중복 허용 여부 (false일 때 중복 허용. default: false)
  • length 
    : 컬럼 길이 지정 (default: 255)

2) 영속성 컨텍스트

: Entity 객체를 효율적으로 쉽게 관리하기 위해 만들어진 공간

  • CRUD과정을 효율적으로 처리하기 위해 JPA는 영속성 컨텍스트에 Entity객체들을 저장하여 관리하면서 DB와 소통함
  • 영속성 컨텍스트에 접근하여 Entity 객체들을 조작하기 위해서는 EntityManager가 필요
  • 개발자들은 EntityManager를 사용해 Entity를 CRUD 할 수 있음.
  • EnityManage는 EntityManagerFactory를 통해 생성

 

3) EntityManagerFactory

: 한 DB당 하나만 생성되어 애플리케이션이 동작하는 동안 사용됨

 

  • EntityManagerFactory를 만들기 위해서는 DB에 대한 정보를 전달해야 됨.
    • /resources/META-INF/ 위치에 persistence.xml 파일을 만들어 정보를 넣어두면 정보 전달할 수 있음

  1. /resource/META-INF/ 위치에 persistence.xml 파일을 만들어 정보를 넣어두면 해당 정보를 읽음.
  2. xml파일의 정보를 토대로 Persistence라는 클래스에 의해서 EntityManagerFactory가 만들어짐
  3. EntityManagerFatory에 의해 EntityManager 생성

4) 트랜잭션

: DB 데이터들을 안전하게 관리하기 위해 생겨난 개념

  • 여러 개의 SQL이 하나의 트랜잭션에 포함될 수 있다는 것이 가장 큰 특징
    • 모든 SQL이 성공적으로 수행되면 DB에 영구적으로 반영.
      SQL 중 단 하나라도 실패한다면 모든 변경 되돌림.

 

 

  • 영속성 컨텍스트에 Entity 객체를 저장했다고 해서 DB에 바로 반영되지 ❌

  • 영속성 컨텍스트로 관리하고 있는 변경이 발생한 객체들의 정보를 ActionQueue에 전부 가지고 있다가 마지막에 한 번에 요청해 변경 반영

 

@Test
@DisplayName("EntityTransaction 성공 테스트")
void test1() {
    EntityTransaction et = em.getTransaction(); // EntityManager 에서 EntityTransaction 을 가져옵니다.

    et.begin(); // 트랜잭션을 시작합니다.

    try { // DB 작업을 수행합니다.

        Memo memo = new Memo(); // 저장할 Entity 객체를 생성합니다.
        memo.setId(1L); // 식별자 값을 넣어줍니다.
        memo.setUsername("Robbie");
        memo.setContents("영속성 컨텍스트와 트랜잭션 이해하기");

        em.persist(memo); // EntityManager 사용하여 memo 객체를 영속성 컨텍스트에 저장합니다.

        et.commit(); // 오류가 발생하지 않고 정상적으로 수행되었다면 commit 을 호출합니다.
        // commit 이 호출되면서 DB 에 수행한 DB 작업들이 반영됩니다.
    } catch (Exception ex) {
        ex.printStackTrace();
        et.rollback(); // DB 작업 중 오류 발생 시 rollback 을 호출합니다.
    } finally {
        em.close(); // 사용한 EntityManager 를 종료합니다.
    }

    emf.close(); // 사용한 EntityManagerFactory 를 종료합니다.
}
  • et.begin()
    : 트랜잭션을 시작하는 명령어
  • et.commit()
    : 트랜잭션의 작업들을 영구적으로 DB에 반영하는 명령어
  • et.rollback()
    : 오류가 발생했을 때 트랜잭션의 작업을 모두 취소하고 이전 상태로 되돌리는 명령어

 

  • Entity 클래스는 DB에 매핑이 되는 것이기 때문에 조심스럽게 다뤄야 함.
    그러므로 setter는 필요한 곳에만 달아줘야 함.

5) 영속성 컨텍스트의 기능

1차 캐시

  • 영속성 컨텍스트는 내부적으로 "캐시 저장소"라는 것을 가지고 있음
    • 저장하는 Entity 객체들이 1차캐시(캐시 저장소)에 저장됨
    • 캐시 저장소는 Map 자료구조 형태로 되어있음.
      • key ➡️ @Id로 매핍한 기본키(식별자 값) 저장
      • value ➡️ 해당 Entity 클래스의 객체 저장
      • 영속성 컨텍스트는 캐시 저장소 Key에 저장한 식별자값을 사용하여 Entity 객체를 구분하고 관리
  • 1차 캐시가 있어 DB 조회 횟수가 줄어듦.
  • DB row 한 개당 객체 한 개가 사용되는 것을 보장함.

 

영속성 컨텍스트의 캐시저장소 활용

  • Entity 저장

    • em.persist(memo); 메서드가 호출되면 memo Entity 객체를 캐시 저장소에 저장.
  • Entity 조회
    1. 캐시 저장소에 조회하는 Id가 존재하지 않은 경우
      1. 캐시 저장소 조회
      2. DB SELECT 조회 후 캐시 저장소에 저장
    2. 캐시 저장소에 조회하는 Id가 존재하는 경우
      em.find(memo.class, 1); 호출 시 캐시 저장소에 식별자 값이 1이면서 Memo Entity 타입인 값이 있는지 조회 후 값이 있다면 해당 Entity 객체 반환
  • Entity 삭제
    1. 삭제할 Entity 조회 후 캐시 저장소에 없다면 DB에 조회해서 저장
    2. em.remove(entity); 호출시 삭제할 Entity를 DELETED 상태로 만든 후 프랜잭션 commit후 Delete SQL이 DB에 요청 됨.

 


flush()

: 영속성 컨텍스트의 변경 내용들을 DB에 반영하는 역할 수행
(쓰기 지연 저장소의 SQL들을 DB에 요청하는 역할)

  • 트랜잭션 commit 후 추가적으로 em.flush(); 메서드를 호출

변경 감지(Dirty Checking)

: 변경하고 싶은 데이터가 있다면 데이터를 조회하고 해당 Entity 객체의 데이터를 변경하면 자동으로 Update SQL이 생성되고 DB에 반영되는 것

  • 영속성 컨텍스트에 저장된 Entity가 변경될 때마다 Update SQL이 쓰기 지연 저장소에 여러 번 요청해야하기 때문에 저장되면 비효율적이기 때문에 변경 감지 과정을 통해 이러한 문제 해결

'내일배움캠프(Sparta) > Spring' 카테고리의 다른 글

[Spring] SpringBoot의 JPA  (0) 2023.11.07
[Spring] Entity의 상태  (0) 2023.11.07
[Spring] ORM / JPA / Hibernate  (0) 2023.11.07
[Spring] IoC / DI / Bean  (0) 2023.11.07
[Spring] 3 Layer Architecture  (0) 2023.11.03