티스토리 뷰
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 프로그래밍을 참고하여 작성했습니다.
'JPA' 카테고리의 다른 글
양방향 연관관계(@OneToMany, mappedBy) (0) | 2024.04.25 |
---|---|
단방향 연관관계(@ManyToOne, @JoinColumn) (0) | 2024.04.24 |
JPA 데이터베이스 스키마 자동 생성 (0) | 2024.04.22 |
JPA 매핑 어노테이션(@Entity, @Table) (0) | 2024.04.21 |
패러다임의 불일치 (0) | 2024.04.16 |
- 준영속
- 단일 테이블 전략
- onetoone
- 스키마 자동 생성
- 비영속
- 1차 캐시
- 엔티티 매니저
- @OneToMany
- @Table
- @Id
- @Cacheable
- 최적화
- N + 1
- @GeneratedValue
- 연관관계
- @joincolumn
- 변경감지
- 메일
- @Entity
- Redis
- 영속성 컨텍스트
- JPA
- 즉시 로딩
- @TransactionalEventListener
- 조인 전략
- 비동기
- mappedBy
- @MappedSuperclass
- 인메모리 db
- @ManyToOne