티스토리 뷰

JAVA

Hibernate란?

Karlie_dev 2026. 1. 5. 00:47

❓ 이 글을 쓰게 된 이유

주로 MyBatis를 사용해 개발하다 보니 Hibernate라는 기술은 익숙한 이름이었지만, 정작 “Hibernate가 무엇이냐”는 질문에는 늘 추상적인 설명밖에 하지 못했다. ORM과 JPA에 대한 기본적인 개념은 알고 있었고, 가볍게 JPA를 사용해 본 경험도 있었지만, Hibernate가 어떤 역할을 하고 어떤 책임을 지는지 명확하게 설명하기는 쉽지 않았다.

이번 글은 그동안 어렴풋하게 알고 있던 개념들을 정리하고, Hibernate를 보다 정확하게 이해하기 위해 작성한 기록이다. 이를 위해 Hibernate 자체부터 설명하기보다는, 먼저 ORM과 JPA라는 기본 개념부터 다시 짚어본다.

1. ORM(Object-Relational Mapping)

ORM(Object-Relational Mapping)은 객체 지향 언어의 객체와 관계형 데이터베이스의 테이블 간 구조적·사고적 차이를 완화하기 위한 개발 패러다임이다.

1.1. ORM이 해결하려는 핵심 문제

RDB 중심 개발(MyBatis 스타일)에서 반복적으로 겪는 문제들은 다음과 같다.

  • SQL 중심 사고 → 객체 모델이 SQL에 종속됨
  • CRUD SQL 과도한 중복
  • 연관관계(1:N, N:M) 표현의 복잡성
  • 영속성 관리(Insert/Update 판단)를 개발자가 직접 수행

ORM은 테이블 기준 사고를 객체 기준으로 바꾸고, SQL 작성 중심을 객체 상태 변경 중심으로 바꾸며, 개발자가 직접 Insert 와 Update 를 결정하는 것을 프레임워크가 상태를 추적하도록 바꾼다.

1.2. 핵심 개념

  • 엔티티 (Entity)
    • 테이블과 매핑되는 도메인 객체
  • 영속성 컨텍스트 (Persistence Context)
    • 엔티티의 생명주기와 상태를 관리하는 1차 캐시 공간
  • 변경 감지 (Dirty Checking)
    • 트랜잭션 커밋 시점 또는 flush 시점에 객체 변경 사항을 감지하여 UPDATE SQL을 생성·실행
  • 연관관계 매핑
    • FK 대신 객체 참조로 관계 표현

2. JPA (Java Persistence API)

자바에서 ORM을 표준화한 스펙이다. JPA는 구현체가 아니며, 인터페이스와 규약의 집합이자, “이렇게 ORM을 구현하라”고 적혀 있는 명세(specification)이다.

2.1. JPA의 제공 범위

  • 엔티티 매핑 어노테이션 (ex. @Entity, @Id, @OneToMany 등)
  • 영속성 컨텍스트 개념
  • 트랜잭션 범위
  • JPQL (객체 기반 쿼리 언어)
  • EntityManager 인터페이스

3. Hibernate

위에서 이야기한 자바 객체 중심으로 영속성(Persistence)을 관리하는 ORM 구현체다.

3.1. Hibernate의 역할

Hibernate는 JPA에서 정의한 개념과 계약을 실제 코드와 런타임 동작으로 구현하는 ORM 엔진이다.

  • SQL 생성 및 실행
  • 영속성 컨텍스트 관리
  • 변경 감지(Dirty Checking)
  • 1차 캐시, 2차 캐시
  • Lazy Loading / Proxy
  • Dialect 기반 DB 방언 처리

🔍 4. 조금 더 자세히

4.1. 영속 객체

JPA에서 객체는 4개의 상태 중 하나를 갖는다.

4.1.1. 비영속 (Transient)

Member m = new Member();
m.setName("kim");

그냥 자바 객체 중 하나이며 DB에 영향을 끼치는 것도 없으며, 이는 Hibernate의 관심사도 아니다.

4.1.2. 영속 (Persistent)

Member m = em.find(Member.class, 1L);

EntityManager를 통하는 순간, Hibernate가 해당 객체를 영속성 컨텍스트에 등록한다.

그리고 현재 상태를 스냅샷으로 만들고, 변경 감시가 시작된다.

또, 이때 동일성을 보장한다.

4.1.3. 준영속 (Detached)

em.clear(); // 또는 트랜잭션 종료

객체는 살아 있으나, Hibernate에서 관리하지 않고, 변경해도 DB에 반영되지 않는다.

4.1.4. 삭제 (Removed)

em.remove(member);
🚨여기서 em은 EntityManager이며, 실제로는 EntityManager를 직접 쓰는 경우는 거의 없다. Spring Data JPA에서 EntityManager를 감싼 추상화를 이미 제공하고 있다.

Spring Data JPA 에서 개발자는 JpaRepository 에 의존하고, 실제 구현은 SimpleJpaRepository 가 EntityManager를 감싸서 제공한다.

 

Mybatis 에서는 영속 객체 개념이 아예 존재하지 않는다.

Member m = mapper.selectById(1L);
m.setName("new");

객체는 그냥 DTO로 존재하고, 변경에 대한 감지로 이루어지지 않을 뿐더러, Update 쿼리를 직접 호출해야 한다.

즉, JPA에서 정의한 ‘영속 객체’란 구현체(Hibernate)가 상태를 추적 대상으로 관리하는 객체를 의미한다.

4.2. 변경 감지 (Dirty Checking)

영속 상태인 엔티티의 필드의 값이 바뀌었는지 Hibernate가 추적했다가, 트랜잭션 커밋(또는 flush) 시점에 UPDATE를 자동으로 만들어 DB에 반영하는 매커니즘이다.

Hibernate/JPA의 핵심 철학은 “개발자가 언제 UPDATE를 실행할지 지시하는 것”이 아니라, “객체 상태가 변경되면 DB 상태는 ORM 구현체(Hibernate)가 책임지고 동기화 한다”는 데 있다.

4.2.1. Dirty Checking이 일어나는 조건

  1. 엔티티가 영속 상태(Persistent)여야 함
    1. em.find()로 조회했거나, em.persist()로 영속화 했거나
  2. 트랜잭션 안에서 변경이 발생해야 함 (@Transactional)
  3. 커밋 시점(or flush())에 Hibernate가 스냅샷(조회 당시 상태)와 현재 상태를 비교해 차이점이 있는 경우
@Entity
@Table(name = "users")
public class User {
	@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;

	@Column(nullable = false)
	private String name;

	protected User() {}

	public User(String name) {
		this.name = name;
	}

	public void changeName(String name) {
		this.name = name;
	}

	public Long getId() { return id; }
	public String getName() { return name; }
}
@Service
@RequiredArgsConstructor
public class UserService {
	private final UserRepository userRepository;

	@Transactional
	public void changeUserName(Long userId, String newName) {
		User user = userRepository
			.findById(userId)
			.orElseThrow(() -> new IllegalArgumentException("not found"));

		user.changeName(newName);
	}
}

changeUserName 메소드는 트랜잭션 안에 있으며, 내부 엔티티가 영속 상태이며, 변경이 발생하였으므로 Dirty Checking 이 발생하는 조건을 모두 만족한다.

해당 메소드가 종료될 때(트랜잭션 커밋 시점)에 Dirty Checking이 발생하고 Update가 실행되는 것이다.

🎆 총 정리

각 단계의 책임을 나누면 다음과 같다.

  • ORM : 개념
    • 언어 독립적
  • JPA : 계약서
    • ORM을 자바에서 쓰기 위한 표준 API
    • 인터페이스 + 어노테이션 + 규칙
  • Hibernate : 구현체로 계약서(JPA)대로 실제 일을 하는 엔진
    • JPA 인터페이스 구현
    • 실제 기능 담당

결국, ORM 은 객체와 RDB를 매핑하려는 패러다임이고, JPA는 그 패러다임을 자바에서 표준화한 명세이며,
Hibernate는 JPA 명세를 실제로 구현한 대표적인 ORM 프레임워크다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/02   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
글 보관함