1. ORM이란

지금까지 SQL을 직접 써서 DB에 데이터를 넣었습니다. Java 코드에서 SQL을 쓰면 이런 모습입니다:

// JDBC로 직접 SQL 작성 (옛날 방식)
public Post findById(Long id) {
    String sql = "SELECT id, title, content, author, created_at, updated_at FROM post WHERE id = ?";
    PreparedStatement pstmt = connection.prepareStatement(sql);
    pstmt.setLong(1, id);
    ResultSet rs = pstmt.executeQuery();

    if (rs.next()) {
        Post post = new Post();
        post.setId(rs.getLong("id"));
        post.setTitle(rs.getString("title"));
        post.setContent(rs.getString("content"));
        post.setAuthor(rs.getString("author"));
        // ... 필드가 많으면 이 작업이 끝없이 반복
        return post;
    }
    return null;
}

문제점이 명확합니다. SQL을 직접 쓰고, ResultSet에서 값을 하나씩 꺼내서 Java 객체에 넣어야 합니다. 테이블이 10개면 이런 코드가 수십 개 생깁니다.

Java 객체 (Post)     ←→  ORM  ←→     DB 테이블 (post)
─────────────               ─────────────────
id (Long)            ←→     id (BIGINT)
title (String)       ←→     title (VARCHAR)
content (String)     ←→     content (TEXT)
createdAt (LocalDateTime) ←→ created_at (DATETIME)

ORM을 쓰면:

// JPA 방식 (ORM)
Post post = postRepository.findById(1L).orElseThrow();
// 끝. SQL 없음. 매핑 코드 없음.

2. JPA와 Hibernate의 관계

혼동하기 쉬운 개념입니다

JPA (Java Persistence API): 자바 ORM 기술의 표준 인터페이스(스펙)입니다. "이런 기능이 있어야 한다"는 규칙만 정의합니다. 실제 구현은 없습니다.

Hibernate: JPA 스펙을 실제로 구현한 라이브러리입니다. JPA의 구현체 중 가장 유명하고 널리 쓰입니다.

Spring Data JPA: Hibernate 위에 한 번 더 추상화한 스프링 모듈입니다. Repository 인터페이스만 만들면 구현체를 자동으로 생성해줍니다.

Spring Data JPA    ← 우리가 직접 사용하는 계층
     ↓
Hibernate (JPA 구현체)    ← 내부적으로 동작
     ↓
JDBC    ← DB 연결
     ↓
MySQL    ← 실제 DB

우리는 Spring Data JPA를 사용합니다. 직접 Hibernate를 다룰 일은 거의 없습니다.


3. 영속성 컨텍스트 (Persistence Context)

JPA의 가장 핵심 개념입니다. 이걸 이해해야 나중에 발생하는 다양한 문제를 해결할 수 있습니다.

영속성 컨텍스트는 Entity를 관리하는 가상의 공간입니다. JPA는 Entity를 DB에 바로 저장하지 않고, 영속성 컨텍스트라는 중간 단계를 거칩니다.