Java & Spring/JPA

[Spring] JPA 4

nippycloud 2026. 2. 12. 10:23

 

JPA의 PK 등록 전략

 

DB : MySQL

package Study.Board.board;


import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;

import java.time.LocalDateTime;

@Getter
@Entity
@ToString
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Board {

    @Id @GeneratedValue // PK 생성 전략에 대하여
    @Column(name = "board_id")
    private Long id;

    private String title;

    private String content;

    private String password;

    @CreatedDate
    private LocalDateTime createdAt;
    @LastModifiedDate
    private LocalDateTime updatedAt;
    private LocalDateTime deletedAt;

    public Board(String password, String content, String title) {
        this.password = password;
        this.content = content;
        this.title = title;
        createdAt = LocalDateTime.now();
    }
}

 

 

 

1. @GeneratedValue를 사용하지 않는 경우

@Id 
@Column(name = "board_id")
private Long id;

 

@GeneratedValue를 사용하지 않으면 아래처럼 직접 개발자가 setter 또는 생성자 방식으로 PK를 설정해야 한다.

Board board = new Board();
board.setId(1L); // 직접 ID(PK) 설정 필요

em.persist(board);

 

 

2. @GeneratedValue(strategy = GenerationType.IDENTITY)

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "board_id")
private Long id;

 

PK 생성을 DB에 위임하는 전략이다.

MySQL, PostgreSQL에서 주로 활용한다.

사용 시 Auto Increment가 적용된다.

DB에 값이 insert될 때 PK를 비우고 insert 시 DB가 순서대로 PK를 할당한다.

DB에 저장 후 PK 조회가 가능하다. DB 저장 전에 PK 조회 불가

 

em.persist() 호출 시점에 즉시 INSERT 쿼리가 실행되고, 그 직후 DB가 생성한 ID를 조회하여 영속성 컨텍스트 내의 객체에 채운다.

 

단점 : 쓰기 지연 활용 불가, em.persist 시 쓰기 지연이 아니라 즉시 쿼리를 전달한다.

 

 

실제 출력되는 쿼리

[Hibernate] 
drop table if exists board
[Hibernate] 
create table board (
    board_id bigint not null auto_increment,
    created_at datetime(6),
    deleted_at datetime(6),
    updated_at datetime(6),
    content varchar(255),
    password varchar(255),
    title varchar(255),
    primary key (board_id)
) engine=InnoDB

 

 

3. @GeneratedValue(strategy = GenerationType.SEQUENCE)

 

 

4. @GeneratedValue(strategy = GenerationType.TABLE)

1. 시퀀스 테이블 = 번호표(시퀀스) 생성 기계
MySQL의 AUTO_INCREMENT는 테이블 자체에 번호 생성 기능이 붙어 있는 방식이지만, 
하이버네이트의 기본(AUTO) 설정은 별도의 '번호표(시퀀스) 전용 테이블'을 만들어 관리한다.

board_seq 테이블: 번호표를 보관하는 기계

values ( 1 ): "이제부터 번호는 1번부터 발행한다!"라고 기계를 초기 세팅

2. 작동 원리
새 게시글을 저장하려고 하면, 스프링은 board 테이블로 바로 가지 X

먼저 board_seq 테이블에 가서 "다음 번호 몇 번이야?"라고 물어보고 번호를 하나 가져간다.

가져온 번호를 board_id에 할당한 뒤, 비로소 board 테이블에 데이터를 넣는다.

 

 

5. @GeneratedValue

@GeneratedValue만 쓴다면 GenerationType.AUTO가 적용되며, 각 DB에 적절한 전략을 자동으로 정한다.

예시 : @GeneratedValue + MySQL 조합 : TABLE 전략 사용

 


@GeneratedValue, ddl auto : create 일 때 출력되는 쿼리

@Id @GeneratedValue 
@Column(name = "board_id")
private Long id;

 

[Hibernate] 
drop table if exists board
[Hibernate] 
drop table if exists board_seq
[Hibernate] 
create table board (
    board_id bigint not null,
    created_at datetime(6),
    deleted_at datetime(6),
    updated_at datetime(6),
    content varchar(255),
    password varchar(255),
    title varchar(255),
    primary key (board_id)
) engine=InnoDB
[Hibernate] 
create table board_seq (
    next_val bigint
) engine=InnoDB
[Hibernate] 
insert into board_seq values ( 1 )

 

 

 Auto Increment가 동작하지 않는다.

[Hibernate] 
create table board_seq (
    next_val bigint
) engine=InnoDB
[Hibernate] 
insert into board_seq values ( 1 )

 

 

 

'Java & Spring > JPA' 카테고리의 다른 글

[Spring] JPA 5  (1) 2026.03.03
[Spring] JPA 변경 감지  (0) 2026.02.13
[Spring] JPA 3  (0) 2026.02.05
[Spring] JPA 2  (0) 2026.01.28
[Spring] JPA 1  (0) 2026.01.20