DEV Community

junghwan
junghwan

Posted on

JPA @GeneratedValue 전략 완벽 가이드: AUTO, IDENTITY, SEQUENCE, TABLE 차이점과 선택 기준

JPA @GeneratedValue 전략 완벽 가이드: AUTO, IDENTITY, SEQUENCE, TABLE 차이점과 선택 기준


JPA의 @GeneratedValue 전략별 동작 방식과 특징

JPA를 사용하다 보면 엔티티의 기본 키(Primary Key)를 어떻게 생성할지 고민하게 된다. 특히 비식별 관계에서는 대리 키(Surrogate Key)를 기본 키로 사용하는 경우가 많다. JPA는 이를 위해 @GeneratedValue 어노테이션을 제공하며, 다양한 키 생성 전략을 지원한다.

이번 글에서는 @GeneratedValue의 동작 방식과 각 전략의 특징을 자세히 살펴본다.


@GeneratedValue란?

@GeneratedValue는 JPA에서 엔티티의 기본 키 값을 자동으로 생성하도록 설정하는 어노테이션이다. 데이터베이스와 애플리케이션 레벨에서 협력하여 키를 생성하며, strategy 속성을 통해 생성 방식을 지정할 수 있다.

지원되는 주요 전략은 AUTO, IDENTITY, SEQUENCE, TABLE 네 가지이며, 각각의 동작 방식과 장단점은 다음과 같다.


1. GenerationType.AUTO: 데이터베이스에 맡기기

특징

  • JPA 구현체(예: Hibernate)가 사용하는 데이터베이스에 따라 전략을 자동 선택한다.

동작 방식

  • MySQL, PostgreSQL → IDENTITY 방식 사용 (AUTO_INCREMENT 활용)
  • Oracle → SEQUENCE 방식 사용
  • H2 → 설정에 따라 IDENTITY 또는 SEQUENCE 선택

장점

  • 데이터베이스에 의존하지 않고 유연하게 사용할 수 있다.
  • 개발 초기 단계나 DB 종류가 자주 바뀔 때 유용하다.

주의점

  • 명확한 전략이 아니므로 운영 환경에서 의도와 다르게 동작할 가능성이 있다.
  • 운영 환경에서는 명시적으로 지정하는 것이 좋다.

2. GenerationType.IDENTITY: 데이터베이스의 자동 증가 기능 사용

특징

  • MySQL의 AUTO_INCREMENT, SQL Server의 IDENTITY 등 데이터베이스 자체 기능을 활용한다.

동작 방식

  1. persist() 호출 시 즉시 INSERT 쿼리를 실행한다.
  2. 데이터베이스가 AUTO_INCREMENT 또는 IDENTITY 컬럼에서 키 값을 생성한다.
  3. 생성된 키 값을 JPA가 엔티티에 설정한다.

장점

  • 데이터베이스가 키 생성을 담당하므로 구현이 간단하다.
  • 직관적인 방식이며 추가 설정이 거의 필요 없다.

단점

  • persist() 시 즉시 INSERT가 실행되므로 쓰기 지연(Transactional Write-Behind) 이 불가능하다.
  • 여러 엔티티를 한 번에 삽입하는 배치 작업에서 성능이 저하될 수 있다.

사용 예시 (MySQL)

@Entity
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    // ...
}
Enter fullscreen mode Exit fullscreen mode

3. GenerationType.SEQUENCE: 시퀀스를 활용한 키 생성

특징

  • Oracle, PostgreSQL 등에서 지원하는 시퀀스 객체를 활용한다.

동작 방식

  1. persist() 호출 시 JPA가 시퀀스에서 다음 값을 가져온다.
   CALL NEXT VALUE FOR MY_SEQUENCE;
Enter fullscreen mode Exit fullscreen mode
  1. 가져온 값을 엔티티의 식별자에 설정한다.
  2. 트랜잭션 커밋 시점에 INSERT 쿼리를 실행한다.

장점

  • allocationSize를 설정하면 시퀀스 값을 미리 할당받아 성능을 최적화할 수 있다.
  • 쓰기 지연(Transactional Write-Behind)이 가능하여 배치 작업에서 성능이 뛰어나다.

주의점

  • 데이터베이스에 시퀀스 객체가 미리 생성되어 있어야 한다.

사용 예시 (Oracle)

@Entity
@SequenceGenerator(name = "MEMBER_SEQ_GENERATOR", sequenceName = "MEMBER_SEQ", allocationSize = 50)
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
    private Long id;
    // ...
}
Enter fullscreen mode Exit fullscreen mode

4. GenerationType.TABLE: 키 생성 테이블 활용

특징

  • 별도의 키 생성용 테이블을 만들어 기본 키를 관리한다.

동작 방식

  • JPA가 키 생성 테이블에서 값을 조회하고 업데이트하며 키를 생성한다.

장점

  • 모든 데이터베이스에서 동작하기 때문에 이식성이 뛰어나다.

단점

  • 테이블 접근으로 인해 성능이 저하될 수 있으며 잘 사용되지 않는 방식이다.

애플리케이션 vs. 데이터베이스: 키 생성 주체 비교

전략 키 생성 주체 주요 특징
IDENTITY 데이터베이스 DB가 키를 생성하며, JPA는 결과만 받아옴
SEQUENCE JPA JPA가 시퀀스를 호출해 키를 가져옴
TABLE JPA 키 생성용 테이블을 활용
AUTO 데이터베이스에 따라 다름 유연하지만 운영 환경에서 주의 필요

MySQL과 @GeneratedValue

MySQL에서 AUTO_INCREMENT를 사용할 때는 GenerationType.IDENTITY를 선택하는 것이 일반적이다.

JPA는 AUTO_INCREMENT 컬럼을 비워둔 채 INSERT를 수행하고, MySQL이 생성한 값을 받아 엔티티에 설정한다.

CREATE TABLE member (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255)
);
Enter fullscreen mode Exit fullscreen mode

위 테이블과 함께 GenerationType.IDENTITY를 사용하면 자연스럽게 동작한다.


어떤 전략을 선택해야 할까?

  • MySQL / PostgreSQL

    • 간단한 프로젝트라면 IDENTITY로 충분
    • 배치 작업이 많다면 SEQUENCE 고려
  • Oracle

    • 시퀀스를 활용한 SEQUENCE가 적합
  • 배치 작업이 많다면?

    • SEQUENCE의 쓰기 지연과 allocationSize 최적화 활용
  • DB 독립성이 중요하다면?

    • TABLE 고려 가능 (하지만 성능 저하 감수해야 함)

결론

@GeneratedValue는 JPA에서 대리 키를 효율적으로 생성하는 강력한 도구다. 하지만 데이터베이스 종류, 성능 요구사항, 개발 편의성을 고려해 적절한 전략을 선택하는 것이 중요하다.

각 전략의 동작 방식과 특징을 이해하고 프로젝트에 맞는 방식을 선택하면 더욱 효과적인 JPA 활용이 가능할 것이다.

Top comments (0)