❑ JPA(Java Persistence API)란?
➤ JPA(Java Persistence API)란?
- ORM(Object-Relation Mapping) 기술의 표준 사양(또는 명세, Specification)
- Java의 인터페이스로 사양이 정의되어 있고 JPA라는 표준 사양을 구현한 구현체는 따로 있다.
➤ Hibernate ORM
- JPA 표준 사양을 구현한 구현체 : Hibernate ORM, EcliipseLink, DataNucleus
- Hibernate ORM은 JPA에서 정의해둔 인터페이스를 구현한 구현체 중 하나이다.
- JPA에서 지원하는 기능 이외에도 자체적으로 사용하도록 지원하는 API 도 있다.
※ Jakarta Persistence
Java Persistence API 의 약자이지만 현재는 Jakarta Persistence 라고도 불린다.
2019년에 나온 JPA 3.0 버전 부터 Jakarta Persistence 라는 이름으로 바뀌었다.
Jakarta Persistence 라고 바뀌면서 패키지와 속성도 javax.persistence 에서 jakarta.persistence 로 이름이 바뀌었다.
엔터프라이즈 Java 애플리케이션에서 관계형 데이터 관리를 설명하는 Jakarta EE 애플리케이션 프로그래밍 인터페이스 사양(specification)이다.
➤ 데이터 액세스 계층에서의 JPA 위치
데이터 액세스 계층에서 JPA는 상단에 위치한다.
데이터 저장, 조회 등의 작업은 JPA를 거쳐 JPA의 구현체인 Hibernate ORM을 통해서 이뤄진다.
Hibernate ORM은 내부적으로 JDBC API를 이용해서 데이터베이스에 접근한다.
➤ JPA(Java Persistence API)에서 P(Persistence)의 의미
Persistence는 영속성, 지속성이라는 뜻이다.
그렇다면 무엇을 지속시키는 것일까?
엔티티 객체 정보를 지속시킨다는 의미이다.
▶️ 영속성 컨텍스트(Persistence Context)
ORM(Object-relational-mapping)은 객체(Object)와 데이터베이스 테이블의 매핑을 통해 엔티티 클래스 객체 안에 포함된 정보를 테이블에 저장하는 기술이다.
JPA에서는 테이블과 매핑되는 엔티티 객체 정보를 영속성 컨텍스트(Persistence Context)라는 곳에 보관해서 애플리케이션 내에서 오래 지속되도록 한다.
엔티티 정보는 데이터베이스 테이블에 데이터를 저장, 수정, 조회, 삭제하는데 사용된다.
JPA API 중 엔티티 정보를 영속성 컨텍스트에 저장(persist)하는 API를 사용하면 영속성 컨텍스트의 1차 캐시에 엔티티 정보가 저장된다.
JPA 영속성 컨텍스트
- EntityManager 클래스에 의해서 관리된다. -> EntityManagerFactory 객체를 Spring으로부터 DI 받을 수 있다.
- EntityManagerFactory의 createEntityManager() 메서드를 이용해서 EntityManager 객체를 얻을 수 있다. -> JPA API 메서드 사용 가능
- persist() 메서드: 영속성 컨텍스트에 객체의 정보들이 저장된다.
- 저장되었는지 확인하려면 find(조회할 엔티티 클래스의 타입, 조회할 엔티티 클래스의 식별자 값) 메서드 사용
➤ JPA API로 영속성 컨텍스트 이해하기
▶️ JPA API를 사용하기 위한 사전 준비
✅ build.gradle 설정
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
Spring Data JPA 기술을 포함한 JPA API를 사용할 수 있다.
✅ application.yml에 아래 코드 추가
jpa:
hibernate:
ddl-auto: create # (1) 스키마 자동 생성
show-sql: true # (2) SQL 쿼리 출력
※ yml에서 추가한 코드가 제대로 적용되지 않을 때는 공백 레벨을 잘 확인해보자.
Spring Data JDBC에서는 schema.sql 파일에 테이블 생성을 위한 스키마를 직접 작성해주어야 하지만 JPA는 (1)의 코드 하나를 추가함으로써 JPA가 자동으로 데이터베이스에 테이블을 생성해 준다.
▶️ @GeneratedValue
식별자를 생성해주는 전략을 지정할 때 사용
이 애너테이션을 엔티티의 멤버 변수에 추가하면 데이터베이스 테이블에서 기본키가 되는 식별자를 자동으로 설정해준다.
▶️ 영속성 컨텍스트에 저장하기
persist() 를 호출 -> 1차 캐시에 객체가 저장되고, 객체가 쓰기 지연 SQL 저장소에 INSERT 쿼리 형태로 등록이 된다.
영속성 컨텍스트에 객체를 저장하지만 실제 테이블에 정보를 저장하지는 않는다.
JPA가 내부적으로 테이블을 자동으로 생성하고, 테이블의 기본키를 할당해준다.
▶️ 데이터베이스 테이블에도 데이터 저장하기
EntityManager의 getTrancsation() 메서드를 이용하여 Transaction 객체를 얻는다.
(JPA에서는 Transaction 객체를 기준으로 DB 테이블에 데이터를 저장한다.)
Transaction을 시작하기 위해서 begin() 메서드 사용
➡️ persist() 로 객체를 영속성 컨텍스트에 저장
➡️ commit() 메서드 호출하여 영속성 컨텍스트에 저장되어 있는 객체를 DB 테이블에 저장한다.
✔️ persist() : 영속성 컨텍스트의 1차 캐시에 엔티티 클래스의 객체가 저장 + ‘쓰기 지연 저장소’에 INSERT 쿼리가 등록
✔️ commit() : ‘쓰기 지연 SQL 저장소’에 등록된 모든 INSERT 쿼리가 실행 + 실행된 INSERT 쿼리는 쓰기 지연 SQL 저장소에서 제거됨
✔️ find() : 1차 캐시에서 해당 객체가 있는지 조회하고, 없으면 테이블에 SELECT 쿼리를 전송해서 조회
➤ 영속성 컨텍스트와 테이블에 엔티티 업데이트
find() 메서드로 1차 캐시에 저장된 객체를 불러와서 객체에 setter로 데이터를 변경
commit() 메서드로 SQL 저장소에 등록된 UPDATE 쿼리가 실행된다.
✅ setter 메서드로 값을 변경만 해도 commit() 시점에 UPDATE 쿼리가 실행되는 이유?
영속성 컨텍스트에 엔티티가 저장될 경우 저장되는 시점의 상태를 그대로 가지고 있는 스냅샷을 생성한다.
그 후 엔티티의 값을 setter 메서드로 변경한 후, commit()을 하면 변경된 엔티티와 이전에 이미 떠 놓은 스냅샷을 비교한 후 변경된 값이 있으면 쓰기 지연 SQL 저장소에 UPDATE 쿼리를 등록하고 UPDATE 쿼리를 실행
➤ 영속성 컨텍스트와 테이블의 엔티티 삭제
EntityManager의 remove() 메서드를 통해 1차 캐시에 있는 엔티티를 제거하도록 요청
Transaction의 commit() 을 실행하면 영속성 컨텍스트에 1차 캐시에 있는 엔티티를 제거하고, 쓰기 지연 SQL 저장소에 등록된 DELETE 쿼리가 실행된다.
▶️ EntityManager의 flush() API
transaction의 commit() 메서드를 호출하면 JPA 내부적으로 flush() 메서드가 호출되어 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다.
※ 추가로 학습해야할 자료들
JPA와 Hibernate 에서 Entity Lifecycle Model
https://thorben-janssen.com/entity-lifecycle-model/
읽어주셔서 감사합니다.
오개념에 대한 지적은 언제나 환영입니다. 😄
'TIL(Today I Learned)' 카테고리의 다른 글
7/7 (목) [Spring MVC] JPA 기반 데이터 액세스 계층 3️⃣ - Spring Data JPA (0) | 2022.07.16 |
---|---|
7/6 (수) [Spring MVC] JPA기반 데이터 액세스 계층 2️⃣ - JPA 엔티티(Entity)매핑과 연관관계 매핑 (0) | 2022.07.16 |
7/4 (월) [Spring MVC] JDBC 기반 데이터 액세스 계층 2️⃣ (0) | 2022.07.12 |
7/1 (금) [Spring MVC] JDBC 기반 데이터 액세스 계층 1️⃣ (0) | 2022.07.09 |
6/30 (목) JDBC 기반 데이터 액세스 계층 - JDBC란? (0) | 2022.07.06 |