[JPA] 기본 키 매핑

hi·2022년 9월 24일

@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Id

직접 할당

@GeneratedValue

자동 생성

IDENTITY
데이터베이스에 위임, MYSQL

SEQUENCE
데이터베이스 시퀀스 오브젝트 사용, ORACLE
@SequenceGenerator 필요

TABLE
키 생성용 테이블 사용, 모든 DB에서 사용
@TableGenerator 필요

AUTO
방언에 따라 자동 지정, 기본값


IDENTITY 전략

@Entity 
public class Member { 
	@Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
	private Long id;
  • 기본 키 생성을 데이터베이스에 위임
    쿼리에 null로 입력됨

  • 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용
    ex. MySQL의 AUTO_ INCREMENT

  • JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL 실행하지만,
    AUTO_ INCREMENT는 데이터베이스에 INSERT SQL을 실행한 이후 ID 값을 알 수 있음

but, 영속성 컨텍스트에 관리되려면 ID값이 필요하다
따라서 IDENTITY 전략은 예외적으로 em.persist() 시점에 즉시 쿼리를 실행하고 DB에서 식별자를 조회한다 (버퍼링 불가-쿼리를 모아두고 한번에 실행하는 것)


SEQUENCE 전략

  • 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는
    특별한 데이터베이스 오브젝트 ex. 오라클 시퀀스

  • 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용


매핑 @SequenceGenerator

@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; 

name

  • 식별자 생성기 이름
  • 필수값

sequenceName

  • 데이터베이스에 등록되어 있는 시퀀스 이름
  • 기본값 hibernate_sequence

initialValue

  • DDL 생성 시에만 사용됨
  • 시퀀스 DDL을 생성할 때 처음 1 시작하는 수를 지정한다
  • 기본값 1

catalog, schema

  • 데이터베이스 catalog, schema 이름

allocationSize

  • 시퀀스 한 번 호출에 증가하는 수 (성능 최적화에 사용됨)
  • 데이터베이스 시퀀스 값이 하나씩 증가하도록 설정되어 있으면
    값을 반드시 1로 설정해야 한다
  • 기본값 50

특징

영속성 컨텍스트에 넣기 위해 미리 시퀀스를 호출하여 ID값을 가져오고 이후에 쿼리 실행 (버퍼링 O)
👉 성능 문제가 없는 이유는 allocationSize 속성 때문
기본값이 50인데, 시퀀스 한 번 호출시 DB에 50개를 셋팅 -> 메모리에서 하나씩 사용
TABLE 전략도 동일


TABLE 전략

  • 키 생성 전용 테이블을 하나 만들어 데이터베이스 시퀀스를 흉내내는 전략

  • 장점 - 모든 데이터베이스에 적용 가능
    단점 - 성능


매핑 @TableGenerator

create table MY_SEQUENCES ( 
	sequence_name varchar(255) not null, 
	next_val bigint, 
	primary key ( sequence_name ) 
)
@Entity 
@TableGenerator( 
	name = "MEMBER_SEQ_GENERATOR", 
	table = "MY_SEQUENCES", 
	pkColumnValue = “MEMBER_SEQ", allocationSize = 1) 
public class Member { 
	@Id 
	@GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR") 
	private Long id; 

name

  • 식별자 생성기 이름
  • 필수값

table

  • 키생성 테이블명
  • 기본값 hibernate_sequences

pkColumnName

  • 시퀀스 컬럼명
  • 기본값 sequence_name

valueColumnName

  • 시퀀스 값 컬럼명
  • 기본값 next_val

pkColumnValue
키로 사용할 값 이름

  • 기본값 엔티티 이름

initialValue

  • 초기 값, 마지막으로 생성된 값이 기준
  • 기본값 0

allocationSize

  • 시퀀스 한 번 호출에 증가하는 수 (성능 최적화에 사용됨)
  • 기본값 50

catalog, schema

  • 데이터베이스 catalog, schema 이름

uniqueConstraints(DDL)

  • 유니크 제약 조건 지정

권장하는 식별자 전략

  • 기본 키 제약 조건 : not null, unique, 변하지 않음
  • 미래까지 이 조건을 만족하는 자연키는 찾기 어려움
    👉 비즈니스와 관련 없는 대리키(대체키) 사용
  • 예를 들어 주민등록번호도 기본 키로 적절하지 않음
  • 권장 : Long형 + 대체키 + 키 생성전략 사용

0개의 댓글