기본 키는 필드에 @Id를 붙여서 매핑 대상을 지정합니다.
@Id
private Long id;
기본 키를 직접 할당하는 경우도 있지만 데이터베이스가 생성해주는 값을 사용하는 경우도 많습니다. 이때 데이터베이스마다 값을 생성하는 방식이 조금씩 다릅니다.
그래서 JPA에서는 다양한 기본 키 생성 전략을 제공하여 데이터베이스 환경에 맞게 기본 키를 자동으로 생성할 수 있게 도와주고 있습니다.
기본 키를 생성하는 전략에는 직접 할당 방식과 자동 할당 방식 두 가지가 존재합니다.
IDENTITY, SEQUENCE, TABLE 전략을 사용한 대리 키 사용 할당.직접 할당 전략은 애플리케이션에서 기본 키를 코드 등을 통해 직접 할당하는 방식입니다. 기본 키로 사용하고자 하는 필드에 @Id만 붙이면 기본 키를 직접 할당하게 됩니다.
@Id
private Long id;
@Id를 붙일 수 있는 필드 타입은 다음과 같습니다.
boolean, char, byte, short, int, long, float, doubleStringjava.util.Date, java.sql.Datejava.math.BigDecimal, java.math.BigInteger기본 키 직접 할당 시에는 엔티티를 저장하기 전에 엔티티 기본 값을 반드시 넘겨주어야 합니다.
영속성 컨텍스트는 식별자 값으로 엔티티를 구분하기 때문에 엔티티 저장 이전에 기본 키를 반드시 설정해야합니다.
자동 할당에는 AUTO, IDENTITY, SEQUENCE, TABLE 네 가지 전략이 존재합니다.
이 중 IDENTITY, SEQUENCE는 데이터베이스가 시퀀스를 제공하냐 마냐에 따라 선택하는 방식이고 TABLE은 모든 데이터베이스에서 사용 가능합니다.
자동 할당 전략에서는 @Id 외에도 @GeneratedValue를 사용해서 자동 할당 전략을 지정해주어야합니다.
@Id
@GeneratedValue(strategy = GenerationType.전략명)
private Long id;
AUTO 전략은 설정한 데이터베이스 방언에 따라 IDENTITY, SEQUENCE, TABLE 세 전략 중에서 자동으로 선택되게 됩니다.
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
예를 들어 시퀀스를 지원하지 않는 MySQL 방언을 설정해 두었다면 자동으로 IDENTITY 전략이 선택되게 됩니다.
IDENTITY 전략은 MySQL, MariaDB 등 시퀀스를 지원하지 않는 DB에서 사용되는 기본 키 자동 생성 전략입니다. 예를 들어 MySQL에서는 AUTO_INCREMENT를 통해 1부터 증가하는 숫자 값을 자동으로 할당 해줍니다.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
IDENTITY 전략은 엔티티를 데이터베이스에 저장한 뒤 식별자를 조회해서 엔티티의 식별자에 할당합니다.
IDENTITY 전략은INSERT가 수행된 후에 기본 키 값을 조회할 수 있습니다. 따라서 저장한 뒤 바로 기본 키 값을 사용하기 위해서는 다시 id를 조회하기 위한 통신을 수행해야합니다.
이때 JDBC3의Statement.getGeneratedKeys()를 사용하면 데이터 저장과 동시에 기본 키를 취득할 수 있어서 한 번만 통신할 수 있게 만들어줍니다.
SQUENCE 전략은 OracleDB, PostgreSQL 등 SEQUENCE를 제공하는 데이터베이스에서 사용할 수 있는 자동 할당 전략입니다.
시퀀스는 유일한 값을 순서대로 생성하는 데이터베이스 오브젝트입니다.
이 방식에서는 @SequenceGenerator를 이용해서 DB에 미리 생성해둔 시퀀스를 등록해야합니다.
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@SequenceGenerator(
name = "시퀀스 이름",
sequenceName = "DB에 생성해 둔 매핑 대상 시퀀스 이름",
initialValue = 1,
allocationSize = 1
)
private Long id;
@SequenceGenerator의 속성은 다음과 같습니다.
속성 설명 name 기본 키 생성기 이름 (필수) sequenceName DB에 등록된 매핑 대상 시퀀스 이름 initialValue 시퀀스가 DDL로 처음 생성될 때 처음 시작하는 수 지정 allocateSize 시퀀스 한 번 호출에 증가하는 수 (기본 값: 50) catalog, schema 데이터베이스의 catalog, schema 이름
SQUENCE 전략은 IDENTITY와 다르게 먼저 시퀀스를 이용해서 식별자를 조회하고 엔티티에 할당한 뒤 저장하게 됩니다.
allocateSize가 1로 설정된 경우 매 INSERT마다 시퀀스를 조회하게 됩니다. 따라서 기본 값인 50을 사용하면 첫 조회 때 1~50의 식별자들이 조회되어 메모리에 저장되고 50번 동안은 메모리에 저장된 식별자 값이 할당됩니다.
TABLE 전략은 키 생성을 위한 전용 테이블을 하나 정의하여 시퀀스처럼 사용할 수 있게 만든 전략입니다. 시퀀스를 지원하지 않는 DB에서도 시퀀스 기능을 제공하기 위해 있는 기능이기 때문에 방금 본 시퀀스 전략, 시퀀스 개념과 유사합니다.
이 전략에서도 별개의 @TableGenerator를 정의해야합니다.
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@TableGenerator(
name = "user_table_gen",
table = "ID_GENERATOR",
pkColumnName = "GEN_NAME",
valueColumnName = "GEN_VALUE",
pkColumnValue = "USER_ID",
allocationSize = 1
)
private Long id;
기본 키를 생성할 생성 테이블의 예시는 다음과 같습니다. (위 예시랑 컬럼명 등을 맞춤)
CREATE TABLE ID_GENERATOR (
GEN_NAME VARCHAR(100) NOT NULL PRIMARY KEY,
GEN_VALUE BIGINT NOT NULL
);
@TableGenerator의 속성은 다음과 같습니다.
속성 설명 name 기본 키 생성기 이름 table DB에 등록된 매핑 대상 테이블 이름 pkColumnName 생성기 별로 구분할 컬럼 이름 valueColumnName 현재 시퀀스 값 저장 컬럼 이름 pkColumnValue 현재 엔티티를 구분할 식별자 initialValue 처음 생성될 때 처음 시작하는 수 지정 allocationSize 한 번 호출에 증가하는 수