본문 바로가기

JPA

JPA, Hibernate, Spring Data JPA 차이점

JPA, Hibernate, Spring Data JPA의 차이점에 대해서 알아보겠습니다.

 

우리가 JPA를 사용한다고 하지만 개발을 하다 보면 Hibernate, Spring Data JPA라는 용어가 등장합니다.

처음엔 JPA가 Hibernate고 그걸 스프링에서 쓰니깐 Spring Data JPA라고 하겠지 하면서 넘어갔습니다.

하지만 이 용어들에는 차이점이 있었고 이러한 차이점을 알고 개발을 하는 것과 모르고 개발하는 것에는 

차이가 있을 거라 생각해서 정리해 보았습니다.

 

JPA 

JPA는 Java Persistence API의 약자입니다.

관계형 DB의 테이블을 자바의 객체의 개념으로 사용하는 기술의 명칭입니다.

우리가 JPA를 사용한다고 하는 것은 'JPA라는 라이브러리를 사용한다'가 아니라 'RDB를 JPA 방식으로 사용하겠다'라고 하는 것입니다. 

JPA는 기술을 명세해놓은 것이기에 인터페이스로 이루어져 있습니다.

JPA가 정의된 package javax.persistence에서 가장 대표적인 EntityManager를 살펴보겠습니다.

package javax.persistence;

import java.util.List;
import java.util.Map;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.CriteriaUpdate;
import javax.persistence.metamodel.Metamodel;

public interface EntityManager {
    void persist(Object var1);

    <T> T merge(T var1);

    void remove(Object var1);

    <T> T find(Class<T> var1, Object var2);

    <T> T find(Class<T> var1, Object var2, Map<String, Object> var3);

    <T> T find(Class<T> var1, Object var2, LockModeType var3);

    <T> T find(Class<T> var1, Object var2, LockModeType var3, Map<String, Object> var4);

    <T> T getReference(Class<T> var1, Object var2);

    void flush();

    void setFlushMode(FlushModeType var1);

    FlushModeType getFlushMode();

    void lock(Object var1, LockModeType var2);

    void lock(Object var1, LockModeType var2, Map<String, Object> var3);

    void refresh(Object var1);

    void refresh(Object var1, Map<String, Object> var2);
    
    ...
   }

JPA에서 사용하는 기술들이 정의되어 있습니다.

이 기술들을 사용하려면 해당 인터페이스를 상속받아 구현한 클래스가 있어야겠죠??

Hibernate

JPA의 메소드들을 구현해놓은 구현체입니다.

많은 사람들이 JPA의 구현체로 Hibernate를 사용하지만 구현이 맘에 들지 않는다면 다른 구현체를 사용할 수도 있고

자신이 직접 커스텀할수도 있습니다.

나중에 한번 커스텀해보는 것도 좋은 공부가 될 것 같습니다 !!

다음은 JPA, Hibernate의 상속 관계도입니다.

JPA의 EntityManager를 Session에서 상속받고 SessionImpl에서 구현하는 방식으로 되어있고 매니저 팩토리, 트랜잭션도 같은 구조를 보입니다.

(참고로 세션이란 DB 커넥션을 열고 작업하고 닫는 과정을 말합니다. 한 세션에서 트랜잭션들이 독립적으로 실행됩니다.)

저의 추측으로는 엔티티 매니져를 세션의 영역에서 사용하기 때문에 세션에서 상속을 받은것처럼 보이는데 이 부분에 대해서는 더 공부를 해야겠습니다.

 

그러면 이제 우리가 JPA를 사용하려면 Hibernate가 구현해놓은 클래스를 가져와 팩토리를 통해서 엔티티 매니져 인스턴스를 생성하고 직접 영속성 관리를 해가며 사용해야 합니다.

하지만 우리는 스프링에서 엔티티매니져를 직접 사용하지 않았습니다.

왜일까요??

Spring Data JPA

Spring에서 JPA를 편리하게 사용할 수 있도록 한 단계 더 추상화시켜주었습니다.

그렇기에 우리는 Repository라는 인터페이스를 사용하면 엔티티 매니져를 직접 건드리지 않고도 편리하게 JPA를 사용할 수 있습니다.

그리고 우리가 개발하는 Repository 상속 인터페이스에서 메소드 이름을 정해진 규칙에 따라서 정의하는데 Spring에서는 메소드 이름을 확인하고 그에 맞는 쿼리를 날리는 구현체를 알아서 빈으로 등록해 줍니다.

 

그럼 Repository의 기본 구현체인 SimpleJpaRepository 코드를 잠시 보고 넘어가겠습니다.

@Repository
@Transactional(
    readOnly = true
)
public class SimpleJpaRepository<T, ID> implements JpaRepositoryImplementation<T, ID> {
    private static final String ID_MUST_NOT_BE_NULL = "The given id must not be null!";
    private final JpaEntityInformation<T, ?> entityInformation;
    private final EntityManager em;
    private final PersistenceProvider provider;
    @Nullable
    private CrudMethodMetadata metadata;
    private EscapeCharacter escapeCharacter;
    
    ...
    
	@Transactional
	public void deleteById(ID id) {
		Assert.notNull(id, "The given id must not be null!");
		this.delete(this.findById(id).orElseThrow(() -> {
			return new EmptyResultDataAccessException(String.format("No %s entity with id %s exists!", this.entityInformation.getJavaType(), id), 1);
		}));
	}

	@Transactional
	public void delete(T entity) {
		Assert.notNull(entity, "Entity must not be null!");
		if (!this.entityInformation.isNew(entity)) {
			Class<?> type = ProxyUtils.getUserClass(entity);
			T existing = this.em.find(type, this.entityInformation.getId(entity));
			if (existing != null) {
				this.em.remove(this.em.contains(entity) ? entity : this.em.merge(entity));
			}
		}
	}
    
	...
}

 

 

 메소드를 살펴보면 EntityManager의 인스턴스인 em을 사용하는 것을 볼 수 있습니다.

 

 

 

그럼 지금까지 알아본 개념을 그림으로 보겠습니다.

 

 

이제 용어들을 헷갈리지 않고 JPA를 사용합시다!!

 

참고

https://suhwan.dev/2019/02/24/jpa-vs-hibernate-vs-spring-data-jpa/

 

JPA, Hibernate, 그리고 Spring Data JPA의 차이점

개요 Spring 프레임워크는 어플리케이션을 개발할 때 필요한 수많은 강력하고 편리한 기능을 제공해준다. 하지만 많은 기술이 존재하는 만큼 Spring 프레임워크를 처음 사용하는 사람이 Spring 프레�

suhwan.dev

https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html

 

Hibernate ORM 5.4.18.Final User Guide

Fetching, essentially, is the process of grabbing data from the database and making it available to the application. Tuning how an application does fetching is one of the biggest factors in determining how an application will perform. Fetching too much dat

docs.jboss.org

 

'JPA' 카테고리의 다른 글

Lob  (0) 2021.09.22