쉬었음 코리아
취업/잡담Spring JPA에서 게시글 ID를 자동 생성하는 방법
쉬었음 청년
91
0

Spring Boot로 커뮤니티 프로젝트를 만들다 보면 거의 모든 테이블에 id가 필요하다.

회원도 id가 필요하고, 게시글도 id가 필요하고, 댓글도 id가 필요하다.


처음에는 단순히 “번호 하나 붙이면 되는 거 아닌가?”라고 생각했는데, JPA를 쓰다 보면 이 번호를 어떻게 생성할지도 꽤 중요한 부분이라는 걸 알게 된다.

이번 글에서는 내가 게시글 엔티티를 만들면서 사용한 @GeneratedValue와 SEQUENCE 전략에 대해 정리해보려고 한다.

실제 게시글 엔티티의 ID 생성 코드

게시글 엔티티의 일부 코드는 아래와 같다.

코드리뷰.png

이 코드는 게시글이 저장될 때 id 값을 자동으로 만들어주는 역할을 한다.

게시글을 저장할 때마다 개발자가 직접 id = 1, id = 2, id = 3 이런 식으로 넣는 것이 아니라, JPA와 데이터베이스가 알아서 기본 키 값을 생성해준다.

@Id는 무엇일까?

먼저 @Id는 해당 필드가 엔티티의 기본 키라는 뜻이다.

데이터베이스 테이블로 보면 id 컬럼이 Primary Key 역할을 하는 것이다.

게시글 테이블에 글이 100개 있다면 각각의 글을 구분할 수 있는 고유한 번호가 필요하다.
그 역할을 하는 게 바로 id다.

커뮤니티에서 게시글 상세 페이지 주소가 /post/1, /post/2 이런 식으로 만들어지는 것도 결국 이 id 값을 기준으로 게시글을 찾기 때문이다.

@GeneratedValue는 무엇일까?

@GeneratedValue는 기본 키 값을 자동으로 생성하겠다는 뜻이다.

여기서 중요한 부분은 strategy다.

strategy는 ID를 어떤 방식으로 만들 것인지 정하는 옵션이다.

JPA에서 자주 볼 수 있는 전략은 대표적으로 다음과 같다.

AUTO
IDENTITY
SEQUENCE
TABLE
UUID

이 중에서 내가 사용한 방식은 SEQUENCE다.

GenerationType.SEQUENCE란?

SEQUENCE는 데이터베이스의 시퀀스를 사용해서 ID 값을 생성하는 방식이다.

쉽게 말하면 데이터베이스 안에 “번호표 기계”를 하나 만들어두는 느낌이다.

게시글을 저장하려고 하면 JPA가 데이터베이스에게 이렇게 묻는다.

다음 게시글 번호 하나 주세요.

그러면 데이터베이스 시퀀스가 다음 번호를 준다.

그 번호가 게시글의 id로 들어간다.

즉, 게시글을 저장할 때마다 시퀀스가 순서대로 번호를 발급해주는 구조다.

@SequenceGenerator는 왜 필요할까?

@SequenceGenerator는 JPA에게 어떤 시퀀스를 사용할지 알려주는 설정이다.

@SequenceGenerator( name = "post_seq", sequenceName = "post_seq_id", allocationSize = 50 )

여기서 각각의 의미는 다음과 같다.

name = "post_seq"

JPA 내부에서 사용할 시퀀스 생성기 이름이다.

그리고 위에서 @GeneratedValue에 적은 generator = "post_seq"와 연결된다.

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "post_seq")

즉, @GeneratedValue에서 “post_seq라는 생성기를 쓸게”라고 말하고,

@SequenceGenerator에서 “post_seq는 이런 설정이야”라고 알려주는 구조다.

다음으로 sequenceName은 실제 데이터베이스 시퀀스 이름이다.

sequenceName = "post_seq_id"

데이터베이스에 만들어질 시퀀스 이름을 post_seq_id로 지정한 것이다.

allocationSize = 50은 무슨 뜻일까?

처음 보면 제일 헷갈리는 부분이 이거다.

allocationSize = 50

이 설정은 ID 값을 하나씩 매번 데이터베이스에서 가져오는 것이 아니라, 일정 개수만큼 미리 확보해서 사용하겠다는 뜻이다.

예를 들어 allocationSize = 50이면 JPA가 시퀀스 번호를 사용할 때 매번 DB에 요청하지 않고, 일정 범위의 번호를 미리 가져와서 사용한다.

쉽게 비유하면 이렇다.

매번 게시글을 저장할 때마다 번호표 기계 앞으로 가는 게 아니라,

번호표 50장을 미리 뽑아두고 하나씩 사용하는 방식이다.

이렇게 하면 게시글을 저장할 때마다 데이터베이스에 계속 ID 번호를 요청하지 않아도 되기 때문에 성능상 이점이 생길 수 있다.

다만 처음 공부할 때는 allocationSize 때문에 ID 값이 생각보다 크게 건너뛰는 것처럼 보일 수도 있다.

예를 들어 테스트 중에 ID가 1 다음에 52처럼 보이는 경우가 생기면, 이 설정과 시퀀스 동작 방식을 의심해볼 수 있다.

그래서 작은 테스트 프로젝트에서는 allocationSize = 1로 두는 경우도 많고, 실제 서비스에서는 성능을 고려해서 50 같은 값을 사용하기도 한다.

IDENTITY와 SEQUENCE는 뭐가 다를까?

처음 JPA를 공부할 때는 IDENTITY를 많이 보게 된다.

@GeneratedValue(strategy = GenerationType.IDENTITY)

IDENTITY는 ID 생성을 데이터베이스의 자동 증가 컬럼에 맡기는 방식이다.

MySQL의 AUTO_INCREMENT를 생각하면 이해하기 쉽다.

반면 SEQUENCE는 데이터베이스의 시퀀스 객체를 사용한다.

PostgreSQL이나 Oracle에서는 시퀀스 전략을 많이 사용한다.

차이를 간단히 정리하면 이렇다.

IDENTITY - DB의 자동 증가 컬럼 사용 - 저장 시점에 ID가 생성됨 - MySQL에서 자주 사용 SEQUENCE - DB의 시퀀스 객체 사용 - ID 값을 미리 가져올 수 있음 - PostgreSQL, Oracle에서 자주 사용 이번 게시글 엔티티에서는 아래와 같은 방식으로 ID를 생성했다. @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "post_seq") @SequenceGenerator( name = "post_seq", sequenceName = "post_seq_id", allocationSize = 50 ) private Long id; 이 설정의 핵심은 다음과 같다. @Id - 이 필드가 기본 키라는 뜻 @GeneratedValue - 기본 키 값을 자동으로 생성하겠다는 뜻 GenerationType.SEQUENCE - 데이터베이스 시퀀스를 사용해서 ID를 생성하는 방식 @SequenceGenerator - 어떤 시퀀스를 사용할지 설정하는 어노테이션 allocationSize - ID 값을 몇 개 단위로 미리 확보해서 사용할지 정하는 값 처음에는 @GeneratedValue를 단순히 “ID 자동 생성” 정도로만 생각했는데, 직접 프로젝트에 적용해보니 데이터베이스 종류와 ID 생성 방식도 같이 생각해야 한다는 걸 알게 됐다. 특히 PostgreSQL을 사용하는 프로젝트라면 SEQUENCE 전략을 이해해두면 좋다. 게시글, 댓글, 회원처럼 계속 데이터가 쌓이는 엔티티에서는 ID 생성 방식이 단순한 문법이 아니라 서비스 구조와도 연결되기 때문이다.

0
0

댓글 0

댓글 불러오는 중...

실시간 인기글