JPA 개념 정의
JPA는 자바 애플리케이션에서 객체와 관계형 데이터베이스를 매핑하기 위한 ORM 표준 인터페이스이다.
JPA는 명세에 해당하고, 실제 구현체는 Hibernate에서 담당한다. 즉, JPA는 "어떻게 동작해야 하는지"를 정의하고, Hibernate는 "실제로 그렇게 동작하도록 만드는" 라이브러리이다.
- JPA는 인터페이스
- JPA는 자바 표준 명세
- "데이터 저장할 때, 인터페이스 명칭을 이렇게 정하자"라고 약속한 규칙 모음
- Hibernate는 구현체
- JPA라는 인터페이스를 실제로 코드로 구현한 라이브러리. 일반적으로 JPA + Hibernate이 표준으로 쓰임
JPA를 왜 사용할까?
이 이유는 앞서 정리했던 ORM이 필요한 이유와 거의 동일하다.
객체 중심 개발
- SQL이 아닌 객체 중심으로 데이터 처리
- 연관관계를 FK가 아닌 객체 참조로 표현
order.getMember().getName();
생산성 향상
- CRUD 자동 생성
- 반복적인 SQL 및 매핑 코드 제거
유지보수성과 확장성
- 테이블 구조 변경 시 SQL 수정 최소화
- DB 종속성 감소
JPA의 핵심 구성 요소
JPA의 핵심 구성요소는 ORM의 핵심 구성 요소와 거의 비슷하나 Hibernate 등의 추가적인 요소들이 있다.
엔티티
- DB 테이블과 매핑되는 자바 클래스(객체)
- JPA가 관리하는 대상
- 비즈니스 로직의 중심
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
private String name;
}
EntityManagerFactory
- EntityManager를 생성하는 팩토리
- 애플리케이션 전체에서 하나만 생성
- 무겁고 비용이 큼
EntityManager
영속성 컨텍스트에 접근하여 엔티티를 저장, 조회, 수정, 삭제하는 핵심 인터페이스이다. (스레드 간 공유를 금지한다)
각 EntityManager 인스턴스는 특정 데이터 저장소에 존재하는 관리되는 엔티티 인스턴스 집합인 영속성 컨텍스트와 연결된다. EntityManager 인터페이스는 영속성 컨텍스트와 상호 작용하여 엔티티들을 관리한다.
- 엔티티의 생명주기를 관리
- 영속성 컨텍스트에 접근하는 창구
em.persist(entity);
em.find(Member.class, 1L);
em.remove(entity);
Persistence Context (영속성 컨텍스트)

엔티티를 관리하는 논리적인 공간이다. (애플리케이션과 DB 사이에서 객체를 보관하는 가상의 영역)
- 1차 캐시
- 동일성 보장
- 변경 감지(Dirty Checking)
- 쓰기 지연(Write-behind) : 트랜잭션 커밋하기 전까지는 실제로 DB에 쿼리가 전송되지 않게 하는 것. 앞에서 생성된 쿼리들을 한 번에 일괄적으로 전송이 가능하다.
Entity e1 = em.find(Entity.class, 1L);
Entity e2 = em.find(Entity.class, 1L);
// e1 == e2 (true)
// 동일성 보장
Transaction
데이터 변경 작업의 논리적 단위이다.
- JPA는 트랜잭션 기반 동작
- 커밋 시점에 SQL 실행
transaction.begin();
transaction.commit();
JPA 구현체 (Hibernate)
- JPA는 명세(인터페이스)
- 실제 구현은 Hibernate, EclipseLink 등
- Spring Boot에서는 기본적으로 Hibernate 사용 (표준)
JPA 메서드
표준 JPA - EntityManager 주요 메서드
EntityManager가 제공하는 기본 메서드들이다. 영속성 컨텍스트를 직접 다룰 때 사용한다.
| 메서드 | 설명 | 비고 |
| persist(entity) | 엔티티를 영속성 컨텍스트에 저장 (DB에 INSERT 준비) | 신규 등록 |
| find(Entity.class, id) | 특정 ID의 엔티티를 조회 | 1차 캐시 확인 후 DB 조회 |
| remove(entity) | 엔티티를 삭제 상태로 변경 (DB에 DELETE 준비) | 삭제 |
| merge(entity) | 준영속 상태의 엔티티를 영속 상태로 변경 (Update 유사) | 병합 |
| flush() | 영속성 컨텍스트의 변경 내용을 DB에 즉시 반영 | SQL 전송 |
| clear() | 영속성 컨텍스트를 완전히 비움 | 1차 캐시 제거 |
Spring Data JPA - JpaRepository 주요 메서드
일반적인 Spring Boot 프로젝트에서 Repository 인터페이스를 만들 때, 보통 JpaRepository를 상속하여 생성한다. EntityManager를 한 번 더 감싸서 편리한 기능을 제공해준다고 보면 된다.
| 서드 | 설명 | 대응 SQL |
| save(S) | 엔티티 저장 및 수정 (ID 유무에 따라 Insert/Update) | INSERT / UPDATE |
| findById(ID | ID로 단건 조회 (결과를 Optional로 반환) | SELECT ... WHERE id = ? |
| findAll() | 전체 엔티티 조회 | SELECT * |
| count() | 전체 엔티티 개수 반환 | SELECT COUNT(*) |
| delete(entity) | 특정 엔티티 삭제 | DELETE |
| deleteById(ID) | ID를 기준으로 삭제 | DELETE ... WHERE id = ? |
| existsById(ID) | 특정 ID의 데이터 존재 여부 확인 | SELECT COUNT(...) > 0 |
JPA의 전체적 흐름
JPA가 어떻게 동작하는지 레이어별로 시각화하자면 아래와 같다.

JPA는 어떻게 동작할까?
JPA 동작의 핵심 - 영속성 컨텍스트
JPA에서 가장 핵심적인 부분은 엔티티를 영구 저장하는 환경인 영속성 컨텍스트이다. 이는 애플리케이션과 데이터베이스 사이에서 객체를 관리하는 가상의 논리공간(데이터베이스) 역할을 한다.
영속성 컨텍스트의 4가지 상태는 다음과 같다. (Entity Lifecycle)
- 비영속 (New): 객체만 생성되고 JPA와 연결되지 않은 상태.
- 영속 (Managed): EntityManager를 통해 객체가 영속성 컨텍스트에 저장된 상태. 여기서부터 JPA가 관리
- 준영속 (Detached): 영속성 컨텍스트에 저장되었다가 분리된 상태.
- 삭제 (Removed): 삭제를 요청한 상태.
Entity 저장 동작 (persist 호출 시점)
Persist 호출
@Transactional
public void saveMember() {
Member member = new Member("Song");
em.persist(member);
}
다음과 같이 persist한 시점에서는 EntityManager를 통해 영속성 컨텍스트에 의해 1차 캐시에 저장되게 된다. (아직 DB 접근 X) 이는 영속성 컨텍스트의 쓰기 지연이라는 특성때문이다. JPA는 SQL을 바로바로 실행하지 않고 모아두는 특성이 있다.
즉, JPA에서는 persist()를 호출하면 바로 INSERT SQL이 실행되지 않고, 엔티티가 영속성 컨텍스트에 저장된다. 이후 트랜잭션 커밋 시점에 flush가 발생하면서 쓰기 지연 상태였던 INSERT SQL이 실행되고 DB에 반영되게 된다.
트랜잭션 커밋 시점
transaction.commit();
트랜잭션 커밋을 하고 난 이후에는 영속성 컨텍스트에서 아래와 같이 수행된다.
- Dirty Checking (변경된 엔티티 있는지 검사)
- SQL Flush (쓰기 지연 SQL 실행)
+--------------------------------------+
| Persistence Context |
|--------------------------------------|
| member (영속 상태) |
| |
| ▶ Flush 발생 |
| ▶ INSERT SQL 실행 |
+--------------------------------------+
|
v
INSERT INTO member(name)
VALUES ('song');
|
v
[ Database ]
persist, commit, flush 요약
persist()
- 영속성 컨텍스트 저장
- 쓰기 지연 SQL 저장
flush()
- SQL 실행
- 트랜잭션 유지
commit()
- flush 자동 실행
- 트랜잭션 종료
commit & flush 순서

Entity 조회 동작
Member member = em.find(Member.class, 1L);
EntityManager
↓
Persistence Context (1차 캐시 확인) => 존재하면 1차 캐시에서 바로 반환
↓
없으면 Hibernate → JDBC → DB (SELECT문 SQL 생성)
↓
조회 결과를 엔티티로 변환
↓
Persistence Context에 저장 (엔티티 생성, 1차 캐시 저장)
Entity 수정 동작
@Transactional
public void changeMember(Long id) {
Member member = em.find(Member.class, id);
member.setName("newName");
}
일단 엔티티매니저에서 update와 관련된 함수는 따로 없다. 즉, em.update()는 JPA에서 존재하지 않으므로 쓸 수 없다!
영속 상태 + 스냅샷
Member member = em.find(Member.class, id);
이 시점에 JPA는 아래와 같은 일들을 한다.
- 엔티티를 영속 상태로 관리
- 최초 조회 시점의 스냅샷을 내부에 저장
스냅샷 = "처음 조회했을 때의 상태"
값 변경 시점 (아무 일도 안일어남)
member.setName("newName");
Dirty Checking (변경 감지)
- 변경된 필드가 발견되면
- UPDATE SQL 자동 생성
Transaction Commit
|
v
Persistence Context
|
v
Snapshot vs Entity 현재 값 비교
flush 시점에 SQL 실행
- flush 시점에 SQL 실행
- 트랜잭션은 아직 유지
- 영속성 컨텍스트는 유지됨
UPDATE member SET name = 'newName' WHERE id = ?
따라서 엔티티의 변경 동작원리는 요약하자면 아래와 같다.
조회(find)
- 영속 상태
- 스냅샷 저장
값 변경
- SQL 실행 X
commit
- dirty checking
- update SQL 생성
- flush
- DB 반영
JPA의 변경 동작 원리를 총정리하자면 다음과 같다.
https://ksh-coding.tistory.com/153
[JPA] JPA, Spring Data JPA의 내부 동작 원리 알아보기
0. 들어가기 전이전에 대부분의 프로젝트에서 JPA를 사용해서 SQL을 작성하지 않고추상화된 메소드를 사용하여 영속화 계층에 접근하고, DB에 SQL을 반영했습니다. 이번에 개인적으로 JPA를 사용할
ksh-coding.tistory.com
https://velog.io/@kmg1997/JPA%EC%9D%98-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC
JPA의 동작 원리
JPA는 Java Persistence API의 약자로, 자바 언어를 사용하여 데이터베이스와 관련된 작업을 더 쉽게 수행할 수 있도록 도와주는 기술이다. JPA를 사용하면 객체 지향 프로그래밍과 데이터베이스 간의
velog.io
https://brunch.co.kr/@anonymdevoo/47
Spring Data JPA 기본 구조와 동작원리
hibernate 코드로 이해하는 Spring Data JPA | Spring Data JPA(이하 스프링 JPA)는 Spring Data의 모듈로 JPA 기반의 데이터 접근 레이어(Data Access Layer)를 편하게 구현할 수 있도록 지원하는 프레임워크이다. 관계
brunch.co.kr
https://devraphy.tistory.com/513
3. JPA의 내부구조와 동작
0. 개요 - 이전 포스팅에서 기본적인 JPA의 구조에 대해서 알아보았다. - 이번 포스팅에서는 JPA가 왜 이러한 기본구조를 갖는지, 그 내부구조와 동작은 어떻게 되는지 알아보자. 1. JPA의 핵심 - JPA
devraphy.tistory.com
'TIL' 카테고리의 다른 글
| [TIL] 동시성 문제와 낙관락/비관락 (0) | 2026.02.04 |
|---|---|
| [TIL] JPA 엔티티 생명주기 (0) | 2026.01.28 |
| [TIL] ORM (0) | 2026.01.26 |
| [TIL] AWS와 k8s (0) | 2025.10.28 |
| [TIL] 무중단배포에 대해 (0) | 2025.10.28 |