Spring

JpaReporitory vs EntityManager

JUNGKEUNG 2021. 11. 23. 14:49

JpaRepository란?


  • Spring Framework에서 제공하는 JpaRepository를 제공해준다.
  • JpaRepository는 인터페이스이다.
  • JpaRepository는 자동으로 클래스를 만들고 Bean을 생성해준다.
  • CRUD처리를 위한 공통 인터페이스 제공
@Repository
public interface MemberRepository extends JpaRepository<Member, Integer> {
}
  • <>안에는 엔티티 클래스 이름과 ID 필드 타입이 지정된다. 주의할 점은 "기본형의 경우, 래퍼 클래스를 지정한다는 점이다. 위에 코드에 보면 기본형 int가 래퍼 클래스를 지정하여 Integer로 해준걸 확인 할수가 있다.
  • 또 하나 주의해야 할 것은 어노테이션이다. 클래스의 선언 앞에 @Repository라는 어노테이션이 붙어져 있다. 그러면 이 인터페이스가 JpaRepository임을 나타낸다. 이는 반드시 붙여 두어야 한다.

 

 

 

EntityManager


  • EntityManager는 영속성 컨텍스트이다
  • 영속성 컨텐스트란?
  • 엔티티를 영구 저장하는 환경을 뜻한다.
  • 애플리케이션과 데이터베이스 사이에서 객체를 보관하는 가상의 데이터베이스 같은 역할을 한다.
  • 엔티티 매니저를 통해 엔티티를 저장하거나 조회하면 에티티 매니저 영속성 컨텍스트에 엔티티를 보관하고 관리한다.
em.persist(member);

엔티티 매니저를 사용해 엔티티를 영속성 컨텍스트에 저장한다는 의미이다

 

 

 

영속성 컨텍스트의 특징


  • Java 영역에서 데이터를 관리하여 DB접근을 최적화하는 역할을 담당한다.
  • 엔티티 매니저를 생성할 때 하나 만들어진다.
  • 엔티티 매니저를 통해서 영속성 컨텍스트에 접근하고 관리할 수 있다.

 

 

 

생명주기


엔티티는 4가지 상태가 존재한다

1. 비영속 : 영속성 컨텍스트와 연관이 없는 상태

2. 영속 : 영속성 컨텍스트에서 관리 중인 상태

3. 준영속 : 영속성 컨텍스트에 저장되어 있었으나 분리된 상태

4. 삭제 영속성 컨텍스트에서 완전히 삭제된 상태

 

 

 

영속


  • EntityManager를 통해 데이터를 영속성 컨텍스트에 저장했다.
  • JPA는 일반적으로 id 필드가 존재하지 않으면 예외를 뱉어내는데, 영속 상태의 엔티티를 관리하기 위해서다.
  • id로 데이터를 관리하기 때문에 꼭 필요한 것이다.

이 상태가 되면 몇 가지의 장점을 갖게 된다.

  1. 1차 캐시
    • em.find(key)를 호출하면 영속성 컨텍스트에 캐시된 데이터를 먼저 찾는다.
    • 캐시된 데이터가 없다면 DB에 접근하여 데이터를 로드하고 1차 캐시 데이터에 저장한다.
    • 1차 캐시의 존재로 Java 영역에서 REPEATABLE READ 등급의 트랜잭션 격리 수준을 활용한다.
  2. 동일성 보장
    • JPA를 통해 불러온 데이터는 모두 캐시 데이터에 저장되기 때문에 같은 id를 가진 데이터는 같은 데이터이다.
      • 일반적으로 Java에서 '같다'라는 기준은 Identity(hashcode) / Equality(equals)이다.
      SomeEntity a = em.find(SomeEntity.class, "1");
      SomeEntity b = em.find(SomeEntity.class, "1");
      // a == b : true (Identity)
      // a.equals(b) : true (Equality)
  3. 트랜잭션 지원하는 쓰기 지연
    • Transaction이 시작된 이후 JPA가 생성한 쿼리는 모두 쓰기 지연 저장소에 저장된다.
    • commit이 수행되면 저장된 모든 쿼리를 실행한다.
  4. 변경 감지
    • SQL을 직접 활용하여 개발하면 update문을 수행할 때 매우 귀찮은 점이 있다.
    • 컬럼 1개, 2개, 3개, ... N개를 수정해야 할 때를 모두 쿼리로 작성해야 하는 것이다.
    • 이렇게 되면 비즈니스 로직은 SQL에 의존할 수밖에 없다.
    • JPA는 데이터를 저장하기 전 영속성 컨텍스트에 저장된 데이터가 있는지 확인한다.
    • 동일 데이터가 존재하면 update, 없으면 insert를 수행한다(upsert).
    • JPA가 실제로 수행하는 쿼리는 모든 컬럼을 변경한다.
      • 컬럼이 굉장히 많은(30개 이상) 테이블이 아니면 성능에 크게 영향을 미치지 않는다.
      • 엔티티 클래스에 @DynamicUpdate를 붙여주면 SET절에 변경된 데이터만 삽입된다.
  5. 지연 로딩

 

 

 

준영속

영속 상태의 엔티티를 detach 시키거나 영속성 컨텍스트 자체가 초기화 / 종료되면 컨텍스트 내부의 모든 데이터는 준영속 상태가 된다.

// 1.
em.detach(someEntity);
// 2.
em.close();
// 3.
em.clear();

삭제

em.remove(someEntity);

플러시

(flush)플러시를 수행하면 아래 순서대로 동작한다.

  1. 데이터의 변경을 감지한다.
  2. 생성된 쿼리를 쓰기 지연 저장소에 등록한다.
  3. commit되면 저장되어 있던 쿼리를 모두 수행한다.

em.flush()를 활용하면 직접 플러시할 수 있다.

  1. 영속성 컨텍스트의 변경 내용을 DB에 반영하는 절차이다.
  2. 엔티티를 영속성 컨텍스트와 DB 양쪽에서 모두 삭제한다.
  3. 관리되지는 않는 상태이지만 JPA의 지원을 받지 못할 뿐, 정상적인 데이터를 갖는 인스턴스이다.
  4. 원래 영속 상태였으나 영속성 컨텍스트에서 분리되어 더 이상 관리하지 않는 데이터가 된 상태이다.

 

 

 

참고자료


https://private-space.tistory.com/81

https://velog.io/@neptunes032/JPA-%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EB%9E%80

https://joont92.github.io/jpa/Spring-Data-JPA/

https://araikuma.tistory.com/329

'Spring' 카테고리의 다른 글

객체 지향 프로그래밍  (0) 2022.06.01
Spring 과 Spring boot  (0) 2022.06.01
엔티티 설계 주의점  (0) 2021.11.21
Maven vs Gradle  (0) 2021.11.05
Spring 이란?  (0) 2021.07.14