• 기본 키 매핑 방법
    • @Id만 사용해 직접 할당
    • @GeneratedValue로 자동 생성
      • IDENTITY
      • SEQUENCE
      • TABLE
      • AUTO : 방언에 따라 자동 지정. 기본값

IDENTITY 전략

  • 기본 키 생성을 데이터베이스에 위임
  • 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용
  • ex) MySQL의 AUTO_ INCREMENT
  • JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL을 모아서 실행하는 데, AUTO_ INCREMENT의 경우는 데이터베이스에 INSERT SQL을 실행한 이후에 ID 값을 알 수 있다. 그렇기 때문에 IDENTITY 전략은 em.persist() 시점에 즉시 INSERT SQL을 실행하고 DB에서 식별자를 조회할 수 있도록 지원하므로 트랜잭션 커밋 시점에 INSER SQL을 모아서 실행하지 않는다.
@Entity
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

SEQUENCE 전략

  • 데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트를 사용
  • ex)오라클의 시퀀스
  • @SequenceGenerator 필요
  • 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용
  • em.persist() 시점에 시퀀스의 다음 값을 불러와 영속성 컨텍스트의 PK에 세팅하기 때문에 트랜잭션 커밋 시점에 INSERT SQL을 모아서 실행할 수 있다.
  • allocationSize의 기본값이 50인 것은 call next value가 발생하면 DB에서는 50까지 증가시켜놓고 메모리에서 50까지 사용하고 메모리에서 50을 다 사용했을 때 다시 call next value가 일어날 수 있도록 성능을 늘린 것이다. (미리 값을 웹 서버에 올려둬서 사용하는 방식)
@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;
}
  • @SequenceGenerator의 속성
    • name : 식별자 생성기 이름 (필수)
    • sequenceName : 매핑할 데이터베이스 시퀀스 이름. 기본값 = hibernate_sequence
    • initialValue : DDL 생성 시에만 사용되며, 시퀀스 DDL을 생성할 떄 처음 시작하는 수를 지정한다. 기본값 = 1
    • allocationSize : 시퀀스 한 번 호출에 증가하는 수를 지정한다. 성능 최적화에 사용되며 데이터베이스 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 이 값을 반드시 1로 설정해야 한다. 기본값 = 50
    • catalog, schema : 데이터베이스 catalog, schema 이름

TABLE 전략

  • 키 생성 전용 테이블을 하나 만들어 데이터베이스 시퀀스를 흉내내는 전략
  • 장점은 모든 데이터베이스에 적용이 가능하나 단점은 성능상 떨어진다.
  • @TableGenerator 필요
  • DB에서 관례로 쓰는 것을 사용하기 때문에 잘 쓰이지 않는다.
@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;
}
  • 다음과 같이 생성된다.
create table MY_SEQUENCES (
    sequence_name varchar(255) not null,
    next_val bigint,
    primary key ( sequence_name )
)
  • @TableGenerator 속성
    • name : 식별자 생성기 이름 (필수)
    • table : 키 생성 테이블명. 기본값 = hibernate_sequences
    • pkColumnName : 시퀀스 컬럼명. 기본값 = sequence_name
    • valueColumnNa : 시퀀스 값 컬럼명. 기본값 = next_val
    • pkColumnValue : 키로 사용할 값 이름. 기본값 = 엔티티 이름
    • initialValue : 초기 값 지정. 마지막으로 생성된 값이 기준이다. 기본값 = 0
    • allocationSize : 시퀀스 한 번 호출에 증가하는 수(성능 최적화에 사용된다.) 기본값 = 50
    • catalog, schema : 데이터베이스 catalog, schema 이름
    • uniqueConstraints(DDL) : 유니크 제약 조건을 지정할 수 있다.

권장 식별자 전략

  • 기본키 제약 조건은 not null, 변하면 안 된다.
  • 미래까지 이 조건을 만족하는 자연키는 찾기 어렵다. 대리키(대체키)를 사용하자.
  • Long형 + 대체키 + 키 생성 전략을 사용하자.