JPA 기본 키 자동 생성 전략

2025. 1. 18. 18:18·BackEnd/JPA

JPA에는

@Entity
public class Users{
	
    @Id
    private long id;
}

@Id 어노테이션을 통해 기본키로 설정할 필드를 지정할 수 있습니다.

 

 

여기서 기본키 값을 생성해주는

@Entity
public class Users{
	@Id
    @GeneratedValue
    private long id;
}

 

어노테이션이 있는데 여기서 사용할 수 있는 전략이 4가지 있습니다.

 

 

 

1. Auto

@Entity
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
}

AUTO 전략은 JPA에서 기본 키를 자동으로 생성할 때 사용되는 기본 전략입니다. 이 전략은 JPA 구현체(예: Hibernate)가 사용하는 데이터베이스에 맞춰 가장 적합한 방식으로 기본 키를 생성하도록 합니다.

 

AUTO 전략의 동작 방식

  • @GeneratedValue(strategy = GenerationType.AUTO)를 사용하면, JPA는 데이터베이스에 적합한 기본 키 생성 전략을 자동으로 선택합니다.
  • Hibernate를 사용한다면, 기본적으로 SequenceStyleGenerator를 통해 키를 생성합니다.
    • 시퀀스(Sequence)를 지원하는 데이터베이스에서는 시퀀스를 사용합니다.
    • **시퀀스를 지원하지 않는 데이터베이스(MySQL 등)**에서는 키 생성용 테이블을 생성하여 사용합니다.
  • 만약, 특정 전략을 지정하지 않고 @GeneratedValue만 사용하면 GenerationType.AUTO가 기본값으로 적용됩니다.

 

 

2.IDENTITY

@Entity
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
}
  • IDENTITY 전략은 말 그대로 데이터베이스의 “IDENTITY 컬럼” 기능을 이용해 기본 키를 생성하는 방식입니다.
  • MySQL의 AUTO_INCREMENT, MSSQL의 IDENTITY 같은 기능을 사용하죠. 데이터베이스가 자동으로 증가되는 숫자를 직접 관리하는 개념입니다.
  • 개발자가 별도로 시퀀스(Sequence)나 테이블을 설정하지 않아도 되고, 데이터를 INSERT하는 시점에 DB가 직접 ID를 결정합니다.

 

정리하자면, IDENTITY를 사용하면 데이터베이스가 알아서 자동 증가값을 만들어 주는 전략이기 때문에, 손쉽게 사용할 수 있습니다. 다만 DB 별로 IDENTITY 기능 지원 여부와 동작 방식이 다를 수 있으니, 사용하는 DB가 IDENTITY를 지원하는지 미리 확인하는 게 좋습니다.

 

 

3.SEQUENCE

@Entity
@SequenceGenerator(
    name = "USER_SEQ_GENERATOR",
    sequenceName = "USER_SEQ", // 데이터베이스 시퀀스 이름
    initialValue = 1, // 시퀀스 초기값
    allocationSize = 1 // 증가값
)
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
                    generator = "USER_SEQ_GENERATOR")
    private long id;
}
  • SEQUENCE 전략은 데이터베이스가 제공하는 “시퀀스(Sequence) 오브젝트”를 이용해 기본 키를 생성합니다.
  • 오라클(Oracle), PostgreSQL 등에서 시퀀스를 지원하고 있죠.
  • 위의 예시처럼 @SequenceGenerator를 활용해 어떤 시퀀스를 쓸 것인지 지정해줄 수 있습니다. initialValue, allocationSize 같은 속성으로 초기값이나 한 번에 증가할 양을 세세하게 조정할 수 있어요.

쉽게 말해, “숫자를 1씩 자동으로 올려주는 기계(시퀀스)를 하나 더 만들어 놓고, 거기서 새로 저장할 데이터의 ID를 뽑아 쓰는 방식”이라고 생각하면 됩니다.

 

 

 

4. TABLE

@Entity
@TableGenerator(
    name = "USER_TABLE_GENERATOR",
    table = "MY_SEQUENCES", // 키 생성 정보를 저장할 테이블 이름
    pkColumnName = "SEQ_NAME", // 시퀀스 이름을 저장할 컬럼
    valueColumnName = "SEQ_NUMBER", // 시퀀스 값(다음에 사용할 번호)을 저장할 컬럼
    pkColumnValue = "USER_SEQ", // 해당 엔티티에 사용할 시퀀스 이름
    initialValue = 1,
    allocationSize = 1
)
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE,
                    generator = "USER_TABLE_GENERATOR")
    private long id;
}
  • TABLE 전략은 별도의 “키 생성 전용 테이블”을 만들고, 그 테이블에서 현재 사용할 수 있는 다음 키 값을 조회하여 ID를 생성하는 방식입니다.
  • 어떤 DB든지 테이블만 만들 수 있으면 쓸 수 있으니 호환성 면에서 유리할 수 있습니다.
  • 하지만 매번 테이블을 조회해야 하므로 다른 전략(IDENTITY, SEQUENCE)에 비해 성능 면에서 약간 손해가 있을 수 있습니다.

“TABLE 전략”은 작은 노트(테이블)에 “현재 다음으로 쓸 번호”를 적어두고, 새로운 데이터가 생길 때마다 그 노트에서 다음 번호를 꺼내 써서 ID를 발급한다고 보시면 됩니다.

 

 

 

 

 

 

4. 개발 중 겪은 문제와 해결 과정

JPA를 처음 사용하면서 개발을 진행하던 중, 로컬 환경에서 MySQL을 사용하며 모든 엔티티의 기본 키 자동 생성 전략을 AUTO로 설정했었습니다.

 

@Entity
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
}

 

그런데, 개발 중 MySQL 스키마에 생성된 테이블들을 확인하다 보니, 예상치 못하게 seq 테이블이 추가로 생성되어 있는 것을 발견했습니다.
예를 들어, users라는 테이블을 생성했을 때, users_seq라는 테이블이 함께 만들어진 것을 볼 수 있었습니다.

 

users
users_seq

 

이 상황에서 “왜 이런 테이블이 생성되는 거지?” 하는 의문이 들었고, 그 이유를 알아보기 위해 조사를 시작했습니다.

 

문제의 원인

JPA에서는 기본 키 생성 전략이 AUTO로 설정된 경우, Hibernate가 내부적으로 SequenceStyleGenerator라는 클래스를 사용합니다.
이 클래스는 다음과 같은 방식으로 작동합니다.

  1. 데이터베이스가 시퀀스(Sequence)를 지원하는 경우, 시퀀스를 이용해 기본 키를 생성합니다.
  2. 데이터베이스가 시퀀스를 지원하지 않을 경우, 테이블(Table) 방식으로 기본 키를 생성합니다.

MySQL은 시퀀스를 지원하지 않기 때문에, JPA는 테이블 방식을 사용하여 기본 키를 생성하려고 합니다.
이를 위해 **seq 테이블(키 생성 전용 테이블)**이 자동으로 생성된 것입니다.
결국, Hibernate가 MySQL의 제약(시퀀스 미지원)을 인지하고 테이블 방식으로 기본 키를 생성하도록 동작했던 것입니다.

 

해결 방법

이 문제를 해결하기 위해 JPA의 기본 키 자동 생성 전략을 MySQL 환경에 적합한 IDENTITY로 변경했습니다.

@Entity
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
}

 

  • IDENTITY 전략은 MySQL의 AUTO_INCREMENT를 활용해 기본 키를 생성합니다.
  • 따라서, 추가적인 seq 테이블이 생성되지 않고, users 테이블 자체의 id 컬럼에서 자동으로 ID 값이 관리됩니다.

 

결과와 배운 점

기본 키 생성 전략을 IDENTITY로 변경한 뒤, 더 이상 불필요한 seq 테이블이 생성되지 않았습니다.
이 과정을 통해 JPA에서의 기본 키 생성 전략이 데이터베이스 환경에 따라 달라질 수 있다는 점을 확실히 이해하게 되었습니다.

 

 

'BackEnd > JPA' 카테고리의 다른 글

SQL 중심 개발의 한계와 JPA 도입의 필요성  (1) 2025.06.10
주소 문자열을 지역 엔티티에 정확히 매핑하기 (feat. 중복 이름 처리)  (0) 2025.05.12
양방향 연관관계에서 편의 메서드를 사용하는 이유  (0) 2025.04.28
JPA 엔티티 설계 쉽게 이해하기: Region 클래스 리팩터링 사례  (0) 2025.04.23
JPA @Id 필드, primitive(int) vs Wrapper(Integer)  (0) 2025.04.21
'BackEnd/JPA' 카테고리의 다른 글
  • 주소 문자열을 지역 엔티티에 정확히 매핑하기 (feat. 중복 이름 처리)
  • 양방향 연관관계에서 편의 메서드를 사용하는 이유
  • JPA 엔티티 설계 쉽게 이해하기: Region 클래스 리팩터링 사례
  • JPA @Id 필드, primitive(int) vs Wrapper(Integer)
hxngpy
hxngpy
비전공 개발자 화이팅
  • hxngpy
    hxngpy
    hxngpy
  • 전체
    오늘
    어제
    • 분류 전체보기 (69) N
      • ssafy 분반테스트 관련 공부 (13)
      • 알고리즘 (2) N
        • 백준 (17)
        • SWEA (1)
      • 자료구조 (0)
      • BackEnd (25)
        • JPA (8)
        • Redis (7)
        • Spring (2)
        • JWT (8)
      • DB (1)
      • 데이터 분석 (1)
      • 꿀팁 (1)
      • CS 공부 (5) N
        • 컴퓨터 구조 (5) N
        • 운영체제 (0)
      • 프로젝트 개발일지 (2)
        • 밥먹다 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백준
    슬라이딩 윈도우
    Spring
    개발일지
    Java
    gitmoji
    spring boot
    컴퓨터 구조
    Redis
    FigJam
    Spring Security
    CS
    연관관계 주인
    JPA
    투포인터
    regionmapping
    JWT
    밥먹다
    addressparsing
    구간 합
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
hxngpy
JPA 기본 키 자동 생성 전략
상단으로

티스토리툴바