직접 기본키를 생성하는 방법
- @Id 어노테이션 만을 사용하여 기본키를 직접 할당해주는 방법이 있다.
기본키를 자동으로 생성하는 방법 4가지
기본키를 자동으로 생성할 때에는 @Id와 @GenerratedValue 어노테이션이 함께 사용되어야 한다.
IDENTITY - @GeneratedValue(strategy = GenerationType.IDENTITY)
- 기본키 생성을 데이터베이스에게 위임하는 방식으로 id값을 따로 할당하지 않아도 데이터베이스가 자동으로 AUTO_INCREMENT를 하여 기본키를 생성해준다.
@Entity
public class PkEx() {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
- JPA는 보통 영속성 컨텍스트에서 객체를 관리하다가 commit이 호출되는 시점에 쿼리문을 실행하게 된다. 하지만 IDENTITY 전략에서는 EntityManager.persist()를 하는 시점에 Insert SQL을 실행하여 데이터베이스에서 식별자를 조회해온다.
- 그 이유는 영속성 컨텍스트는 1차 캐시에 PK와 객체를 가지고 관리를 하는데 기본키를 데이터베이스에게 위임햇기 때문에 EntityManager.persist()호출 하더라도 데이터베이스에 값을 넣기 전까지 기본키를 모르고 있기 때문에 관리가 되지 않기 때문이다.
- 따라서 특별한 경우로 IDENTITY 전략에서는 EntityManager.persist()를 하는 시점에 Insert SQL을 실행하여 데이터베이스에서 식별자를 조회하여 영속성 컨텍스트 1차 캐시에 값을 넣어주기 때문에 관리가 가능해진다.
SEQUENCE - @GeneratedValue(strategy = GenerationType.SEQUNCE)
- 데이터 베이스의 Sequence Object를 사용하여 데이터베이스가 자동으로 기본키를 생성해준다.
- @SequenceGenerator 어노테이션이 필요하다.
@Entity
@SequenceGenerator(
name = "USER_PK_GENERATOR",
sequenceName = "USER_PK_SEQ",
initailValue = 1,
allocationSize = 50
)
public class PkEx() {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator="USER_PK_GENERATOR")
private Long id;
private String name;
}
- SEQUENCE 전략도 IDENTITY 전략과 동일한 문제가 있다. 데이터베이스가 직접 기본키를 생성해 주기 때문이다.
- EntityManager.persist() 가 호출 되기 전에 기본키를 가져와야 하므로 하이버네이트에서 hibernate: call next value for USER_PK_SEQ 을 실행하여 기본키를 가져온다.
- 그 후에 EntityManager.persist()호출하기 때문에 IDENTITY 전략과 다르게 쿼리문을 실행하지 않는다.
- 하지만 SEQUENCE 값을 계속 DB에서 가져와서 사용해야 하기 때문에 성능에 저하를 일으킬 수 있다 . 따라서 allocationSize 의 크기를 적당히 설정하여 성능 저하를 개선시킬 수 있다.
TABLE - @GeneratedValue(strategy = GenerationType.TABLE)
- 키를 생성하는 테이블을 사용하는 방법으로 Sequence와 유사하다.
- @TableGenerator 어노테이션이 필요하다.
@Entity
@TableGenerator(
name = "USER_PK_GENERATOR",
table = "USER_PK_SEQ",
pkColumnValue = "USER_SEQ",
allocationSize = 1
)
public class PkEx() {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator="USER_PK_GENERATOR")
private Long id;
private String name;
}
- TABLE 전략은 모든 데이터베이스에서 사용이 가능하지만 최적화 되어있지 않은 테이블을 사용하기 때문에 성능문제에 이슈가 있다.
AUTO - @GeneratedValue(strategy = GenerationType.AUTO)
- 기본 설정 값으로 각 데이터베이스에 따라 기본키를 자동으로 생성한다.
기본키의 제약조건
- null이면 안된다.
- 유일하게 식별할 수 있어야한다.
- 변하지 않는 값이어야 한다.
권장하는 식별키 구성방법 : Long형 + 대체키 + 그에 맞는 적절한 키 생성전략 사용