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
등 데이터베이스 자체 기능을 활용한다.
동작 방식
-
persist()
호출 시 즉시INSERT
쿼리를 실행한다. - 데이터베이스가
AUTO_INCREMENT
또는IDENTITY
컬럼에서 키 값을 생성한다. - 생성된 키 값을 JPA가 엔티티에 설정한다.
장점
- 데이터베이스가 키 생성을 담당하므로 구현이 간단하다.
- 직관적인 방식이며 추가 설정이 거의 필요 없다.
단점
-
persist()
시 즉시INSERT
가 실행되므로 쓰기 지연(Transactional Write-Behind) 이 불가능하다. - 여러 엔티티를 한 번에 삽입하는 배치 작업에서 성능이 저하될 수 있다.
사용 예시 (MySQL)
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// ...
}
3. GenerationType.SEQUENCE: 시퀀스를 활용한 키 생성
특징
- Oracle, PostgreSQL 등에서 지원하는 시퀀스 객체를 활용한다.
동작 방식
-
persist()
호출 시 JPA가 시퀀스에서 다음 값을 가져온다.
CALL NEXT VALUE FOR MY_SEQUENCE;
- 가져온 값을 엔티티의 식별자에 설정한다.
- 트랜잭션 커밋 시점에
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;
// ...
}
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)
);
위 테이블과 함께 GenerationType.IDENTITY
를 사용하면 자연스럽게 동작한다.
어떤 전략을 선택해야 할까?
-
MySQL / PostgreSQL
- 간단한 프로젝트라면
IDENTITY
로 충분 - 배치 작업이 많다면
SEQUENCE
고려
- 간단한 프로젝트라면
-
Oracle
- 시퀀스를 활용한
SEQUENCE
가 적합
- 시퀀스를 활용한
-
배치 작업이 많다면?
-
SEQUENCE
의 쓰기 지연과allocationSize
최적화 활용
-
-
DB 독립성이 중요하다면?
-
TABLE
고려 가능 (하지만 성능 저하 감수해야 함)
-
결론
@GeneratedValue
는 JPA에서 대리 키를 효율적으로 생성하는 강력한 도구다. 하지만 데이터베이스 종류, 성능 요구사항, 개발 편의성을 고려해 적절한 전략을 선택하는 것이 중요하다.
각 전략의 동작 방식과 특징을 이해하고 프로젝트에 맞는 방식을 선택하면 더욱 효과적인 JPA 활용이 가능할 것이다.
Top comments (0)