“자바 객체로 DB를 직접 다룰 수 없을까?” 라는 고민에서 파생되어 개발되었다.
SQL 중심 개발(JDBC, MyBatis 등)의 한계를 극복하고, 객체 중심 개발을 가능하게 해준다.
Java Persistence API: 자바 ORM(Object-Relational Mapping) 표준 인터페이스이다.
SQL과 JDBC 코드를 직접 작성하지 않아도 객체 중심으로 데이터베이스 작업이 가능하다.
구현체 설명
JPA는 인터페이스(표준)이고, 실제 동작은 구현체(Hibernate 등)가 수행한다.
EntityManagerFactory
애플리케이션 시작 시 1회 생성된다.
JPA 설정을 로드하고, EntityManager를 생성한다.
스프링에서는 자동으로 Bean으로 등록된다.
EntityManager
트랜잭션 단위로 생성되는 실제 작업 관리자이다.
DB 접근, 영속성 컨텍스트 관리 등 핵심 기능을 담당한다.
스프링에서는 @PersistenceContext 또는 @Autowired로 주입 가능하다.
@PersistenceContext
private EntityManager em;
JPA의 가장 핵심적인 개념: "엔티티 상태를 관리하는 1차 캐시 공간"
정의
EntityManager가 관리하는 내부 메모리 공간
엔티티를 조회하거나 저장하면 이 컨텍스트가 관리한다.
생성 타이밍
| 상태 | 설명 |
|---|---|
| 비영속 (Transient) | 영속성 컨텍스트와 무관한 상태이다. |
| 영속 (Persistent) | em.persist()로 등록되어 관리되는 상태이다. |
| 준영속 (Detached) | em.detach() 등으로 관리에서 분리된 상태이다. |
| 삭제 (Removed) | em.remove() 호출된 상태로 커밋 시 삭제가 반영된다. |
1️⃣ 1차 캐시
2️⃣ 동일성 보장
== 비교로도 동일성 판단이 가능하다. (같은 인스턴스가 반환되므로, 개발자가 동일성을 고려하지 않아도 된다.)3️⃣ 쓰기 지연 (Write-behind)
persist() 호출 시 DB에 바로 저장되지 않고, 트랜젝션 단위로 쿼리를 최적화한다. (트랜잭션 commit() 시점에 한 번에 실행된다.)4️⃣ 변경 감지 (Dirty Checking)
setter 등으로 필드 값을 변경하면, 자동으로 update 쿼리가 생성된다.(영속성 컨텍스트에서 관리중인 엔티티의 값이 변경될 경우, 영속성 컨텍스트가 변경을 감지하여 커밋 시점에 데이터를 변경해준다. 즉 개발자가 별도로 update()를 호출하지 않아도 된다.)Member member = em.find(Member.class, 1L);
member.setName("변경됨"); // 커밋 시 자동 update
JPA는 트랜잭션 안에서만 쓰기 지연, 변경 감지, flush 등 주요 기능이 동작한다.
@Transactional이 선언된 메서드 안에서 사용해야 정상 동작된다.
트랜잭션 커밋 시 자동으로 flush() → DB에 반영
| 방식 | 설명 | 장점 | 단점 |
|---|---|---|---|
| 기본 JPA | (EntityManager) | 세밀한 제어 가능 | 코드량 많고 느림 |
| Spring Data JPA | Repository 기반 자동 CRUD | 빠른 개발 가능 | 복잡한 커스터마이징엔 제약 있음 |
flush()
영속성 컨텍스트의 변경사항을 DB에 동기화해주는 기능이다.
커밋 시 자동으로 호출되지만 수동으로도 호출이 가능하다. (em.flush())
JPQL
em.createQuery("SELECT m FROM Member m WHERE m.name = :name")
연관관계 매핑
@ManyToOne, @OneToMany, @JoinColumn 등이 있다.Cascade, FetchType
CascadeType.ALL → 연관 엔티티도 함께 저장/삭제한다.
FetchType.LAZY vs EAGER → 연관 엔티티 조회 전략이다.