티스토리 뷰

JPA

기본 키 매핑(@Id, @GeneratedValue)

pyounani 2024. 4. 23. 11:11

JPA가 제공하는 데이터베이스 기본 키 생성 전략은 다음과 같습니다. 

  • 직접 할당
  • IDENTITY
  • SEQUENCE
  • TABLE
  • AUTO

이렇게 다양한 이유는 데이터베이스 시스템마다 지원하는 방식이 다르기 때문입니다.

하나씩 방법을 살펴보도록 하겠습니다. 

 

1. 직접 할당

기본 키를 직접 할당하기 위해서는 @Id 어노테이션을 사용해 주면 됩니다. 

@Id
private Long id;

 

@Id가 작용 가능한 자바 타임은 아래와 같습니다. 

  • 자바 기본형
  • 자바 Wrapper 형
  • String
  • java.util.Date
  • java.sql.Date
  • java.math.BigDecimal
  • java.math.BigInteger

 

2. IDENTITY

기본 키 생성을 데이터베이스에 위임하는 전략입니다. 주로 MySQL, PostgresSQL, SQL Server 등에서 사용합니다.

@GeneratedValue 어노테이션에 strategy 속성 값을 GenerationType.IDENTITY로 지정해 주면 됩니다. 

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

 

 

MySQL 데이터베이스로 설정했을 경우 아래와 같은 로그를 확인할 수 있습니다.

CREATE TABLE Member (
    id BIGINT GENERATED BY DEFAULT AS IDENTITY, -- IDENTITY 전략 적용
    PRIMARY KEY (id)
);
  • 엔티티가 영속 상태가 되기 위해 식별자가 반드시 필요하기 때문에 em.persist()를 호출하는 즉시 INSERT SQL이 데이터베이스에 전달이 됩니다.
  • 데이터베이스에 저장된 후 엔티티에 식별자 값을 할당하기 위해 조회가 추가로 발생합니다.
  • 이 경우는 트랜잭션을 지원하는 쓰기 지연이 동작하지 않습니다.

 

3. SEQUENCE

데이터베이스가 생성하는 유일한 값을 사용하여 기본 키를 생성합니다. 주로 oracle, postgresSQL, H2 등에서 사용합니다.

@GeneratedValue 어노테이션에 strategy 속성 값을 GenerationType.SEQUENCE 로 지정해 주면 됩니다. 

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

 

 

MySQL 데이터베이스로 설정했을 경우 아래와 같은 로그를 확인할 수 있습니다.

CREATE TABLE Member (
    id BIGINT NOT NULL,
    PRIMARY KEY (id)
);

CREATE SEQUENCE hibernate_sequence
START WITH 1
INCREMENT BY 1; -- SEQUENCE 전략 적용
  • em.persist()를 호출할 때 먼저 데이터베이스 시퀀스를 사용해서 식별자를 조회해 엔티티의 식별자에 할당합니다.
  • 이후에 트랜잭션을 커밋해 플러시가 일어나면 엔티티를 데이터베이스에 저장합니다.

 

추가로 @SequenceGenerator 어노테이션을 활용하여 시퀀스를 직접 지정하여 생성할 수 있습니다. 

@Entity
@Data
@SequenceGenerator(
        name = "ID_SEQ_GENERATOR",
        sequenceName = "ID_SEQ",
        initialValue = 1,
        allocationSize = 1
)
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;
}

 

 

4. TABLE

키 생성 전용 테이블을 만들어 데이터베이스 시퀀스와 유사한 기능을 제공합니다. 이 전략은 테이블을 사용하므로 모든 데이터베이스에 적용할 수 있습니다.

 

우선, 키 생성 용도로 사용할 테이블을 생성해줍니다.

create table MY_SEQUENCES (
    sequence_name varchar(255) not null,
    next_val bigint,
    primary key ( sequence_name )
)

 

@TableGenerator 어노테이션을 이용해 시퀀스용 테이블과 매핑시켜 줍니다.

@Entity
@Data
@TableGenerator(
        name = "MEMBER_SEQ_GENERATOR",
        table = "MY_SEQUENCES",
        pkColumnValue = "MEMBER_SEQ",
        allocationSize = 1
)
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;
}

 

 

5. AUTO

데이터베이스 방언에 따라 IDENTITY, SEQUENCE, TABLE 전략 중 하나를 자동으로 선택합니다.

@GeneratedValue 어노테이션에 strategy 속성 값을 GenerationType.AUTO로 지정해 주면 됩니다. 

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

 

 

MySQL  데이터베이스로 활용했을 때 IDENTITY를 채택하는 것을 확인할 수 있습니다. 

CREATE TABLE Member (
    id BIGINT NOT NULL AUTO_INCREMENT, --IDENTITY 전략사용
    PRIMARY KEY (id)
);

 

👀 IDENTITY가 아니라 AUTO_INCREMENT인데요..?

MySQL에서 AUTO_INCREMENT는 데이터베이스에서 기본 키 또는 고유 열에 자동으로 증가하는 값을 부여할 수 있는 속성입니다.

이 속성은 IDENTITY 전략과 동일한 역할을 수행하지만, MySQL에서는 AUTO_INCREMENT라는 이름으로 구현됩니다.

 

 

 📌 사용하시는 데이터베이스 방언 및 스키마에 맞게 기본 키 전략을 선택해 설정해 주시면 될 것 같습니다.

 

 

 

 

본 포스팅은 자바 ORM 표준 JPA 프로그래밍을 참고하여 작성했습니다.