직접 할당하거나 자동생성 해야 한다.
직접 할당
자동생성
@GeneratedValue를 사용한다.
3가지 옵션이 있다.
IDENTITY
기본키 생성을 데이터베이스에 위임한다.
MySQL, PostgreSQL, SQL Server, DB2 방식과 맞는다.
JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL을 실행
마찬가지로 em.persist() 시점에 즉시 INSERT SQL이 실행되고, DB에서 식별자를 조회 가능하다.
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
SEQUENCE
DB 시퀀스 : 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트이다.
오라클, PostgreSQL, DB2, H2 데이터베이스와 맞는다.
@Entity
@SequenceGenerator(
name = “MEMBER_SEQ_GENERATOR",
sequenceName = “MEMBER_SEQ", //매핑할 데이터베이스 시퀀스 이름
initialValue = 1, allocationSize = 1)
// initialValue : DDL 생성 시 처음 시작하는 수
// allocationSize : 시퀀스 한 번 호출에 증가하는 수
// 시퀀스 값을 얻어오기 위해 persist 할때마다 DB 접근하면 성능이슈
// -> 기본값 50 : 50개만큼 DB에 할당해 두고 메모리에 시퀀스 값 기록하여 사용
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator = "MEMBER_SEQ_GENERATOR")
private Long id;
JPA는 쓰기 지연을 지원하므로, 하나의 트랜잭션 안에서 INSERT 쿼리를 모아서 보내는데, 각각의 INSERT 쿼리마다 시퀀스가 필요하다.
이때 각 시퀀스마다 DB 접속은 넘 비효율액션이므로, 매 트랜잭션마다 50개를 설정했으면 50개 중 필요한 만큼 쓰고 나머진 버린다.
TABLE
키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략이다.
모든 데이터베이스에서 사용 된다.
성능상으로는 그닥 좋지 않다.
create table MY_SEQUENCES (
sequence_name varchar(255) not null,
next_val bigint,
primary key ( sequence_name )
)
@Entity
@TableGenerator(
name = "MEMBER_SEQ_GENERATOR",
table = "MY_SEQUENCES",
pkColumnValue = “MEMBER_SEQ", allocationSize = 1)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "MEMBER_SEQ_GENERATOR")
private Long id;
인프런 JAVA ORM 표준 JPA 프로그래밍 - 기본편