Back_End/JPA

JPA @GeneratedValue 전략

10Biliion 2025. 7. 7. 17:56

 

JPA에서 엔티티의 기본 키(@Id)를 자동 생성하려면 @GeneratedValue를 사용합니다. IDENTITY, SEQUENCE, TABLE 전략 사용에 따라 동작 방식, insert 타이밍, 성능, 동시성 처리 등을 알아보겠습니다.


GeneratedValue 전략 종류

전략 설명 사용 가능한 DB
IDENTITY DB의 auto_increment 사용 MySQL, H2, PostgreSQL 등
SEQUENCE DB 시퀀스 객체를 사용 Oracle, PostgreSQL 등
TABLE 별도 테이블을 생성해 ID 값을 관리 모든 DB (비추)
 

IDENTITY

  • DB의 auto_increment, IDENTITY 컬럼 사용
  • JPA가 persist() 시점에 바로 insert를 실행하고, DB에서 생성된 ID를 받아옴
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

특징

  • insert를 먼저 실행해야 ID 값을 알 수 있으므로 flush()가 강제로 일어남
  • 배치 처리 불가 (insert 쿼리마다 DB round-trip 발생)
  • 트랜잭션 안에서 ID 값을 사전에 예측할 수 없음

장점

  • 설정이 간단하고 MySQL 등에서 기본 전략

단점

  • 성능 낮음 (배치 insert 불가)
  • persist() 시점에 바로 DB 접근

SEQUENCE

  • DB의 시퀀스 객체에서 미리 ID 값을 가져옴
  • 엔티티에 ID를 설정한 후 flush() 시점에 insert
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_seq")
@SequenceGenerator(
    name = "member_seq",
    sequenceName = "member_seq",
    allocationSize = 50
)
private Long id;

특징

  • select nextval('시퀀스')로 미리 ID 확보
  • allocationSize만큼 메모리에 미리 캐싱해두고 사용

장점

  • 배치 insert 가능
  • 성능 우수
  • flush() 이전에 영속성 컨텍스트에 ID 설정 가능

동시성 처리

  • 시퀀스 값을 범위 단위로 미리 가져오므로 동시성 이슈 없이 빠르게 처리 가능

예시

  • allocationSize = 50이면 → Hibernate가 한 번에 50개 ID를 가져오고 메모리에서 차례대로 할당

단점

  • DB에 시퀀스 객체가 있어야 함 (MySQL X, Oracle/Others O)

TABLE

  • 별도의 테이블(id_generator 등)을 생성하여 ID 값을 관리
  • 어떤 DB든 사용할 수 있지만 성능 매우 낮음
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "member_gen")
@TableGenerator(
    name = "member_gen",
    table = "id_generator",
    pkColumnName = "gen_name",
    valueColumnName = "gen_val",
    pkColumnValue = "member",
    allocationSize = 50
)
private Long id;

동작 방식

  • id_generator 테이블을 select → update → insert 트랜잭션 발생
  • 락 필요 → 성능 저하

장점

  • 모든 DB에서 사용 가능

단점

  • DB 락 필수
  • 성능 낮음
  • 복잡도 증가

 

전략 ID 생성 시점 insert 시점 배치 가능 동시성  처리성능 추천 DB
IDENTITY insert 후 persist() ❌ 불가 DB가 알아서 처리 느림 MySQL, H2
SEQUENCE persist() 전에 flush() ✅ 가능 allocationSize로 해결 빠름 Oracle, PostgreSQL
TABLE persist() 전에 flush() ❌ 거의 안 씀 테이블 락 → 느림 매우 느림 거의 사용 안 함
 

 

'Back_End > JPA' 카테고리의 다른 글

JPA 상속관계 매핑 전략  (0) 2025.07.17
JPA 연관관계 매핑 정리  (2) 2025.07.16
JPA 핵심 매핑(Mapping) 개념  (1) 2025.05.08
JPA 영속성 컨텍스트,엔티티 매니저, 그리고 엔티티  (0) 2025.05.08
Spring Data JPA란?  (1) 2025.04.11