JPA란 자바 ORM(Object Relational Mapping) 기술에 대한 API 표준 명세를 의미합니다. 즉, JPA는 특정 기능을 하는 라이브러리가 아니라, ORM을 사용하기 위한 인터페이스를 모아둔 것으로 자바 어플리케이션에서 관계형 데이터베이스를 어떻게 사용해야 하는지를 정의하는 방법 중 한가지 입니다.
또한, JPA는 단순히 명세이기 때문에 구현이 없습니다. JPA를 정의한 javax.persistence 패키지의 대부분은 interface, enum, Exception, 그리고 Annotation들로 이루어져 있습니다.
JPA의 핵심이 되는 EntityManager는 아래와 같이 javax.persistence 패키지 안에 interface 로 정의되어 있습니다.
package javax.persistence;
import ...
public interface EntityManager {
public void persist(Object entity);
public <T> T merge(T entity);
public void remove(Object entity);
public <T> T find(Class<T> entityClass, Object primaryKey);
// More interface methods...
}
JPA를 사용하기 위해서는 JPA를 구현한 Hibernate, EclipseLink, DataNucleus 같은 ORM 프레임워크를 사용해야 합니다.
그 중 우리가 Hibernate를 많이 사용하는 이유는 가장 범용적으로 다양한 기능을 제공하기 때문입니다.
JPA의 구현체 중 하나를 의미하며, Hibernate는 SQL을 사용하지 않고 직관적인 코드를 이용해 데이터를 조작할 수 있습니다. 다만 SQL을 직접 사용하지 않는다고 해서 JDBC API를 이용하지 않는 것은 아닙니다. Hibernate가 지원하는 메소드 내부에서는 JDBC API가 동작하고 있으며, 단지 개발자가 직접 SQL을 작성하지 않을 뿐 입니다.
JPA와 Hibernate는 마치 자바의 interface와 해당 interface를 구현한 class와 같은 관계입니다.
JPA의 핵심인 EntityManagerFactory, EntityManager, EntityTransaction을 Hibernate에서는 각각 SessionFactory, Session, Transaction으로 상속받고 각각 Impl로 구현하고 있음을 확인할 수 있습니다.
Spring Data JPA는 Spring에서 제공하는 모듈 중 하나로 JPA를 쉽고 편하게 사용할 수 있도록 도와줍니다. 기존에 JPA를 사용하기 위해서는 EntityManager를 주입받아 사용해야 하지만 Spring Data JPA는 JPA를 한단계 더 추상화 시킨 Repository 인터페이스를 제공합니다.
Spring Data JPA가 JPA를 추상화 했다는 말은, Spring Data JPA의 Repository의 구현에서 JPA를 사용하고 있다는 것입니다.
즉, 사용자가 Repository 인터페이스에 정해진 규칙대로 메소드를 입력하면, Spring이 알아서 해당 메소드 이름에 적합한 쿼리를 날리는 구현체를 만들어서 Bean으로 등록해줍니다.
Hibernate는 JPA의 구현체이고, Spring Data JPA는 JPA에 대한 데이터 접근의 추상화라고 말할 수 있습니다. Spring Data JPA는 GenericDAO라는 커스텀 구현체를 제공하는데, 이것이 메소드의 명칭으로 JPA쿼리들을 생성할 수 있습니다.
Spring Data를 사용하면 Hibernate, Eclipse Link 등의 JPA 구현체를 사용할 수 있으며, @Transaction 어노테이션을 통해 트랜잭션 영역을 선언하여 관리할 수 있습니다.
Hibernate는 낮은 결합도의 이점을 살린 ORM 프레임워크로써 API 레퍼런스를 제공합니다.여기서 반드시 기억해야할 점은 Spring Data JPA는 항상 Hibernate와 같은 JPA 구현체가 필요합니다.