[TIL] JPA 기본 개념

phdljr·2023년 11월 3일
0

TIL

목록 보기
23/70

Entity

  • JPA에 의해 관리되는 객체
  • DB의 테이블과 매핑됨

영속성 컨텍스트

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

EntityManager

  • 엔티티 객체들을 조작하기 위한 객체
    • 이를 통해서 엔티티 객체를 접근하거나 조작할 수 있음

EntityManagerFactory

  • EntityManager를 관리하는 객체
    • /resources/META-INF/persistence.xml 파일을 통해 정보를 전달해서 EntityManager를 생성

      EntityManagerFactory emf = Persistence.createEntityManagerFactory("memo")
      EntityManager em = emf.createEntityManager();

트랜잭션

  • 트랜잭션 안의 SQL이 하나라도 실패하면, 작업을 시작하기 전으로 되돌림
  • COMMIT: 트랜잭션 단위 작업을 종료

JPA에서의 트랜잭션

  • EntityManager에서 EntityTransaction을 가져와서 진행할 수 있음
@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 를 종료합니다.
}

영속성 컨텍스트의 기능

1. 1차 캐시

  • 내부적으로 캐시 저장소를 가짐
    • find 실행 시, 캐시에 존재하면 DB에 접근하지 않고 바로 반환
    • 객체 동일성을 보장함
  • 읽기, 쓰기, 삭제에 대해 1차 캐시에 상태값을 저장함

2. 쓰기 지연 저장소(Action Queue)

  • 트랜잭션 내에서 발생한 SQL을 저장해둠
  • 커밋(정확히는 flush)이 됐을 때, 저장된 SQL을 한번에 다 실행시킴

3. 변경 감지(Dirty Checking)

  • 엔티티의 변경 사항이 있을때마다 DB로 쿼리를 보내지 않음
    • flush 요청이 왔을 때, 최종적으로 한 번 업데이트 쿼리를 날림
  • 순서
    1. 처음 엔티티를 find로 조회한다. 이때, 처음 상태값을 저장한다.
    2. 변경이 이뤄지고 flush가 호출되면 처음 상태값이랑 현재 값이랑 비교한다.
    3. 해당되는 변경값에 대해 쿼리문을 작성하여 DB로 쿼리를 요청한다.
  • 무조건 트랜잭션이 걸려있어야만 한다.

flush()

  • JPA가 데이터베이스로 작업 요청을 보낼 때 호출되는 메소드
  • 직접 호출도 가능하고, commit()이 호출되면 자동으로 flush()가 호출된다.

JPA에서 데이터 변경에 대한 트랜잭션

  • 조회는 괜찮지만, 변경에 대해선 무조건 트랜잭션 내에서 실행해야 됨
    • INSERT, UPDATE, DELETE

Entity 상태

  • 영속
    • JPA가 관리하는 엔티티
  • 비영속
    • JPA가 관리안하는 엔티티
  • 준영속
    • 관리 했다가 안하는 엔티티
    • clear(), detach(entity), close()
    • merge(entity) 호출 시, 새롭게 엔티티를 만들어서 다시 영속 상태로 만듦
      Memo mergedMemo = em.merge(memo);
      • merge는 수정 또는 저장이 이뤄진다.
      • merge(entity) 동작
        • 파라미터로 전달된 Entity의 식별자 값으로 영속성 컨텍스트를 조회합니다.
          1. 해당 Entity가 영속성 컨텍스트에 없다면?
            1. DB에서 새롭게 조회합니다.
            2. 조회한 Entity를 영속성 컨텍스트에 저장합니다.
            3. 전달 받은 Entity의 값을 사용하여 병합합니다.
            4. Update SQL이 수행됩니다. (수정)
          2. 만약 DB에서도 없다면 ?
            1. 새롭게 생성한 Entity를 영속성 컨텍스트에 저장합니다.
            2. Insert SQL이 수행됩니다. (저장)
  • 삭제
    • 삭제시킴
profile
난 Java도 좋고, 다른 것들도 좋아

0개의 댓글