[JPA] 기본키 매핑 :: 잡다한 프로그래밍
반응형

이번 시간에는 JPA에서 엔티티의 기본 키(@Id) 를 어떻게 매핑하고 생성 전략을 어떻게 선택할지에 대해 알아보자.

기본 키 매핑이란?

JPA에서 @Entity 클래스는 반드시 식별자(PK) 를 가져야 하며, 이 식별자를 통해 엔티티를 구분하고 영속성 컨텍스트에서 관리한다.

기본적으로 다음과 같은 방식으로 식별자를 지정할 수 있다.

@Entity
public class Member {
    @Id
    private Long id; // 직접 지정 (직접 할당 방식) 거의 사용하지 않음
}

 

기본 키 자동 생성 전략 (@GeneratedValue)

IDENTITY DB에 위임 (MySQL 등)
SEQUENCE DB 시퀀스 오브젝트 사용 (Oracle, Postgres 등), @SequenceGenerator 필요
TABLE 키 생성 전용 테이블 사용 (모든 DB 지원, but 느림), @TableGenerator 필요
AUTO 방언(Dialect)에 따라 자동 선택 (기본값)
 

IDENTITY 전략 (DB 너가 알아서 해줘!)

 
@Entity
public class Member {
 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 private Long id;

 

  • DB에 ID 생성 위임 (AUTO_INCREMENT)
  • 대표 DB: MySQL, MariaDB, SQL Server

특징:

  • em.persist() 즉시 INSERT SQL 실행됨 → PK값을 DB에서 받아오기 때문
    • DB에  ID값 생성을 위임 하기 때문에 최초에 ID값이 없어 영속성 컨텍스트에 먼저 저장할 수 없음
    • 따라서 INSERT 쿼리를 먼저 날린후 해당 ID값 으로 영속성 컨텍스트에 저장
    • 따라서 batch insert 지원하지 않음 (하지만 같은 트랜잭션 내에서 성능차이가 그렇게 크진않음..)

 

SEQUENCE 전략

@Entity
@SequenceGenerator(
 name = “MEMBER_SEQ_GENERATOR",
 sequenceName = “MEMBER_SEQ", //매핑할 데이터베이스 시퀀스 이름
 initialValue = 1, allocationSize = 1)
public class Member {
 @Id
 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
 private Long id;

 

  • DB의 시퀀스 오브젝트 사용 → 성능이 우수함
  • 시퀀스 제너레이터를 통해서 시퀀스를 만들어낼 수 있고, 테이블별로 만드는걸 권장함
  • 대표 DB: Oracle, PostgreSQL, DB2, H2

동작 방식:

  1. 먼저 select nextval('member_seq') 로 시퀀스 값을 조회
  2. 해당 값으로 INSERT 실행
  3. 같은 트랜잭션에서 insert 여러 번 하더라도 미리 받은 값에서 순차 사용 가능
  • allocationSize=50이 기본 → 메모리 미리 할당
  • 최초에 조회 후 같은 트랙잭션 내에서 insert 여러번 실행시 50개의 PK를 가지고 있으므로 bulk insert 가능

@SequenceGenerator 주요 속성 정리

속성명 설명 기본값 필수여부
name 식별자 생성기 이름 (@GeneratedValue(generator = "...")와 연결) 없음 O
sequenceName 매핑할 DB 시퀀스 객체 이름 hibernate_sequence X
initialValue 시퀀스 시작 값 (DDL 생성 시에만 사용) 1 X
allocationSize 한 번에 미리 증가시킬 수량 (성능 최적화용, JPA는 메모리 캐싱함) 50 X
  → DB 시퀀스가 1씩 증가하도록 설정되어 있다면 반드시 1로 맞춰야 함    
catalog 시퀀스가 속한 catalog 이름 DB 기본값 X
schema 시퀀스가 속한 schema 이름 DB 기본값 X

 

TABLE 전략

  • 키 생성용 테이블을 직접 만들어서 시퀀스처럼 사용하는 방식
  • 장점: 모든 DB에서 사용 가능
  • 단점: 성능이 매우 느림 → 실무에선 거의 사용 X

이런 방식은 레거시 DB 호환성 때문에 어쩔 수 없을 때만 고려

 

AUTO 전략 (기본값)

  • 방언(Dialect)에 따라 적절한 전략 자동 선택

예:

  • MySQL → IDENTITY
  • Oracle → SEQUENCE
  • H2 → SEQUENCE
 

권장하는 식별자 전략

 

  • PK는 절대 변하지 않는 대리키(대체키)를 Long 타입으로 사용
  • 자연키(주민번호, 이메일 등)는 PK로 부적합 (변경 가능성, 유출 위험 등)
  • 전략 선택:
    • Oracle, PostgreSQL 등 → SEQUENCE + allocationSize 1
    • MySQL → IDENTITY
    • 운영 DB 성능 최적화 필요 → 직접 관리 (e.g., UUID 전략, UUID+time 등)

 

반응형

+ Recent posts