반응형
이번 시간에는 JPA에서 엔티티의 기본 키(@Id) 를 어떻게 매핑하고 생성 전략을 어떻게 선택할지에 대해 알아보자.
기본 키 매핑이란?
JPA에서 @Entity 클래스는 반드시 식별자(PK) 를 가져야 하며, 이 식별자를 통해 엔티티를 구분하고 영속성 컨텍스트에서 관리한다.
기본적으로 다음과 같은 방식으로 식별자를 지정할 수 있다.
@Entity
public class Member {
@Id
private Long id; // 직접 지정 (직접 할당 방식) 거의 사용하지 않음
}
기본 키 자동 생성 전략 (@GeneratedValue)
IDENTITY | DB에 위임 (MySQL 등) |
SEQUENCE | DB 시퀀스 오브젝트 사용 (Oracle, Postgres 등), @SequenceGenerator 필요 |
TABLE | 키 생성 전용 테이블 사용 (모든 DB 지원, but 느림), @TableGenerator 필요 |
AUTO | 방언(Dialect)에 따라 자동 선택 (기본값) |
IDENTITY 전략 (DB 너가 알아서 해줘!)
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
- DB에 ID 생성 위임 (AUTO_INCREMENT)
- 대표 DB: MySQL, MariaDB, SQL Server
특징:
- em.persist() 즉시 INSERT SQL 실행됨 → PK값을 DB에서 받아오기 때문
- DB에 ID값 생성을 위임 하기 때문에 최초에 ID값이 없어 영속성 컨텍스트에 먼저 저장할 수 없음
- 따라서 INSERT 쿼리를 먼저 날린후 해당 ID값 으로 영속성 컨텍스트에 저장
- 따라서 batch insert 지원하지 않음 (하지만 같은 트랜잭션 내에서 성능차이가 그렇게 크진않음..)
SEQUENCE 전략
@Entity
@SequenceGenerator(
name = “MEMBER_SEQ_GENERATOR",
sequenceName = “MEMBER_SEQ", //매핑할 데이터베이스 시퀀스 이름
initialValue = 1, allocationSize = 1)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
private Long id;
- DB의 시퀀스 오브젝트 사용 → 성능이 우수함
- 시퀀스 제너레이터를 통해서 시퀀스를 만들어낼 수 있고, 테이블별로 만드는걸 권장함
- 대표 DB: Oracle, PostgreSQL, DB2, H2
동작 방식:
- 먼저 select nextval('member_seq') 로 시퀀스 값을 조회
- 해당 값으로 INSERT 실행
- 같은 트랜잭션에서 insert 여러 번 하더라도 미리 받은 값에서 순차 사용 가능
- allocationSize=50이 기본 → 메모리 미리 할당
- 최초에 조회 후 같은 트랙잭션 내에서 insert 여러번 실행시 50개의 PK를 가지고 있으므로 bulk insert 가능
@SequenceGenerator 주요 속성 정리
속성명 | 설명 | 기본값 | 필수여부 |
name | 식별자 생성기 이름 (@GeneratedValue(generator = "...")와 연결) | 없음 | O |
sequenceName | 매핑할 DB 시퀀스 객체 이름 | hibernate_sequence | X |
initialValue | 시퀀스 시작 값 (DDL 생성 시에만 사용) | 1 | X |
allocationSize | 한 번에 미리 증가시킬 수량 (성능 최적화용, JPA는 메모리 캐싱함) | 50 | X |
→ DB 시퀀스가 1씩 증가하도록 설정되어 있다면 반드시 1로 맞춰야 함 | |||
catalog | 시퀀스가 속한 catalog 이름 | DB 기본값 | X |
schema | 시퀀스가 속한 schema 이름 | DB 기본값 | X |
TABLE 전략
- 키 생성용 테이블을 직접 만들어서 시퀀스처럼 사용하는 방식
- 장점: 모든 DB에서 사용 가능
- 단점: 성능이 매우 느림 → 실무에선 거의 사용 X
이런 방식은 레거시 DB 호환성 때문에 어쩔 수 없을 때만 고려
AUTO 전략 (기본값)
- 방언(Dialect)에 따라 적절한 전략 자동 선택
예:
- MySQL → IDENTITY
- Oracle → SEQUENCE
- H2 → SEQUENCE
권장하는 식별자 전략
- PK는 절대 변하지 않는 대리키(대체키)를 Long 타입으로 사용
- 자연키(주민번호, 이메일 등)는 PK로 부적합 (변경 가능성, 유출 위험 등)
- 전략 선택:
- Oracle, PostgreSQL 등 → SEQUENCE + allocationSize 1
- MySQL → IDENTITY
- 운영 DB 성능 최적화 필요 → 직접 관리 (e.g., UUID 전략, UUID+time 등)
반응형
'프로그래밍 > JPA' 카테고리의 다른 글
[JPA] 양방향 연관관계와 연관관계의 주인[2] (0) | 2025.06.25 |
---|---|
[JPA] 단방향 연관관계 (0) | 2025.06.24 |
[JPA] 필드와 컬럼 매핑 (1) | 2025.06.19 |
[JPA] 데이터베이스 스키마 자동 생성 (0) | 2025.06.19 |
[JPA] 객체와 테이블 매핑 (0) | 2025.06.19 |