[JPA] 기본 키 매핑 - @Id

Bam·2025년 5월 15일
0

Spring

목록 보기
53/73
post-thumbnail

@Id

기본 키는 필드에 @Id를 붙여서 매핑 대상을 지정합니다.

@Id
private Long id;

기본 키 생성 전략

기본 키를 직접 할당하는 경우도 있지만 데이터베이스가 생성해주는 값을 사용하는 경우도 많습니다. 이때 데이터베이스마다 값을 생성하는 방식이 조금씩 다릅니다.

그래서 JPA에서는 다양한 기본 키 생성 전략을 제공하여 데이터베이스 환경에 맞게 기본 키를 자동으로 생성할 수 있게 도와주고 있습니다.

기본 키를 생성하는 전략에는 직접 할당 방식과 자동 할당 방식 두 가지가 존재합니다.

  • 직접 할당: 애플리케이션에서 기본 키를 직접 할당
  • 자동 할당: IDENTITY, SEQUENCE, TABLE 전략을 사용한 대리 키 사용 할당.

기본 키 직접 할당 전략

직접 할당 전략은 애플리케이션에서 기본 키를 코드 등을 통해 직접 할당하는 방식입니다. 기본 키로 사용하고자 하는 필드에 @Id만 붙이면 기본 키를 직접 할당하게 됩니다.

@Id
private Long id;

@Id를 붙일 수 있는 필드 타입은 다음과 같습니다.

  • 자바 기본형 boolean, char, byte, short, int, long, float, double
  • 자바 Wrapper 클래스
  • String
  • java.util.Date, java.sql.Date
  • java.math.BigDecimal, java.math.BigInteger

기본 키 직접 할당 시에는 엔티티를 저장하기 전에 엔티티 기본 값을 반드시 넘겨주어야 합니다.

영속성 컨텍스트는 식별자 값으로 엔티티를 구분하기 때문에 엔티티 저장 이전에 기본 키를 반드시 설정해야합니다.

기본 키 자동 할당 전략

자동 할당에는 AUTO, IDENTITY, SEQUENCE, TABLE 네 가지 전략이 존재합니다.

이 중 IDENTITY, SEQUENCE는 데이터베이스가 시퀀스를 제공하냐 마냐에 따라 선택하는 방식이고 TABLE은 모든 데이터베이스에서 사용 가능합니다.

자동 할당 전략에서는 @Id 외에도 @GeneratedValue를 사용해서 자동 할당 전략을 지정해주어야합니다.

@Id
@GeneratedValue(strategy = GenerationType.전략명)
private Long id;

AUTO 전략

AUTO 전략은 설정한 데이터베이스 방언에 따라 IDENTITY, SEQUENCE, TABLE 세 전략 중에서 자동으로 선택되게 됩니다.

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

예를 들어 시퀀스를 지원하지 않는 MySQL 방언을 설정해 두었다면 자동으로 IDENTITY 전략이 선택되게 됩니다.

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 전략

SQUENCE 전략OracleDB, PostgreSQLSEQUENCE를 제공하는 데이터베이스에서 사용할 수 있는 자동 할당 전략입니다.

시퀀스는 유일한 값을 순서대로 생성하는 데이터베이스 오브젝트입니다.

이 방식에서는 @SequenceGenerator를 이용해서 DB에 미리 생성해둔 시퀀스를 등록해야합니다.

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@SequenceGenerator(
	name = "시퀀스 이름",
    sequenceName = "DB에 생성해 둔 매핑 대상 시퀀스 이름",
    initialValue = 1,
    allocationSize = 1
)
private Long id;

@SequenceGenerator의 속성은 다음과 같습니다.

속성설명
name기본 키 생성기 이름 (필수)
sequenceNameDB에 등록된 매핑 대상 시퀀스 이름
initialValue시퀀스가 DDL로 처음 생성될 때 처음 시작하는 수 지정
allocateSize시퀀스 한 번 호출에 증가하는 수 (기본 값: 50)
catalog, schema데이터베이스의 catalog, schema 이름

SQUENCE 전략IDENTITY와 다르게 먼저 시퀀스를 이용해서 식별자를 조회하고 엔티티에 할당한 뒤 저장하게 됩니다.

allocateSize가 1로 설정된 경우 매 INSERT마다 시퀀스를 조회하게 됩니다. 따라서 기본 값인 50을 사용하면 첫 조회 때 1~50의 식별자들이 조회되어 메모리에 저장되고 50번 동안은 메모리에 저장된 식별자 값이 할당됩니다.

TABLE 전략

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기본 키 생성기 이름
tableDB에 등록된 매핑 대상 테이블 이름
pkColumnName생성기 별로 구분할 컬럼 이름
valueColumnName현재 시퀀스 값 저장 컬럼 이름
pkColumnValue현재 엔티티를 구분할 식별자
initialValue처음 생성될 때 처음 시작하는 수 지정
allocationSize한 번 호출에 증가하는 수

0개의 댓글