4.6 기본 키 매핑

@Entity
public class Member {

    @Id
    @Column(name = "ID")
    private String id;

◉ JPA가 제공하는 데이터베이스 기본 키 생성 전략

  • 데이터베이스 벤더마다 기본 키 생성을 지원하는 방식이 다름

◉ 기본키 생성 전략 방식

  • 직접 할당 : 기본 키를 어플리케이션이 직접 할당
  • 자동 생성 : 대리 키 사용 방식
    • INDENTITY : 기본 키 생성을 데이터베이스에 위임.
    • SEQUENCE : 데이터베이스 시퀀스를 사용해서 기본 키를 할당.
    • TABLE : 키 생성 테이블을 사용한다.

◉ 기본키 생성 방법

  • 기본 키를 직접 할당 : @Id만 사용
  • 자동 생성 전략 사용 : @GeneratedValue 추가 및 키 생성 전략 선택.

◉ 키 생성 전략 사용을 위한 속성 추가

<property name="hibernate.id.new_generator_mappings" value="true" />

4.6.1

// 기본 키 직접 할당
@Id
@Column(name = "id")
private String id;

@Id 적용 가능한 자바 타입

  • 자바 기본형
  • 자바 래퍼형
  • String
  • java.util.Date
  • java.sql.Date
  • java.math.BigDecimal
  • java.math.BigInteger

기본 키 할당하는 방법

Board board = new Board();
board.setId("id1");         //기본 키 직접 할당
em.persist(board);

4.6.2 IDENTITY 전략

IDENTITY는 기본 키 생성을 데이타베이스에 위임하는 전략.
주로 MySQL, PostgreSQL, SQL Server, DB2, H2에서 사용.

◉ MySQL의 AUTO_INCREMENT 기능

CREATE TABLE BOARD {
    ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    DATA VARCHAR(255)
};

INSERT INTO BOARD(DATA) VALUES('A');
INSERT INTO BOARD(DATA) VALUES('B');

BOARD 테이블 결과

ID DATA
1 A
2 B

◉ IDENTITY 전략

  • 데이터베이스에 값을 저장하고 나서야 기본 키 값을 구할 수 있을 때 사용.
  • em.persist() 호출시 INSERT SQL을 즉시 데이터베이스에 전달.
  • 식별자를 조회해서 엔티티의 식별자에 할당.
  • 쓰기 지연이 동작하지 않는다.
@Entity
public class Professor {
  @Id 
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;
  private String name;
  private long salary;
  ...
}

4.6.3 SEQUENCE 전략

유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트
주로 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용.

시퀀스 관련 SQL

CREATE TABLE BOARD (
    ID BIGINT NOT NULL PRIMARY KEY,
    DATA VARCHAR(255)
)

//시퀀스 생성
CREATE SEQUENCE BOARD_SEQ START WITH 1 INCREMENT BY 1;

시퀀스 매핑 코드

@Entity
@SequenceGenerator(
    name = "BOARD_SEQ_GENERATOR",
    sequenceName = "BOARD_SEQ",
    initialValue = 1,
    allocationSize = 1)
public class Board {

    @Id
    @GeneraedValue(strategy = GenerationType.SEQUNCE,
                    generator = "BOARD_SEQ_GENERATOR")
    private Long id;
}

시퀀스 사용 코드

private static void logic(EntityManager em) {
    Board board = new Board();
    em.persist(board);
    System.out.println("board.id = " + board.getId());
}
  1. 먼저 데이터베이스 시퀀스를 사용해서 식별자를 조회.
  2. 조회한 식별자를 엔티티에 할당.
  3. 엔티티를 영속성 컨텍스트에 저장.
  4. 트랜잭션 커밋.
  5. 플러시 - 데이터베이스에 저장.

주의

  • SequenceGenerator.allocationSize 기본값이 50.
  • 반드시 1로 설정.

TABLE 전략

키 생성 전용 테이블을 하나 만들고 여기에 이름과 값을 사용할 컬럼을 만들어 데이터베이스 시퀀스를 흉내내는 전략.
테이블을 사용하므로 모든 데이터베이스에 적용 할 수 있다.

TABLE 전략 키 생성 테이블

create table MY_SEQUENCES (
    sequence_name varchar(255) not null,
    next_val bigint,
    primary key (sequence_name)
)

TABLE 전략 매핑 코드

@Entity
@TableGenerator(
    name = "BOARD_SEQ_GENERATOR",
    table = "MY_SEQUENCES",
    pkColumnValue = "BOARD_SEQ", allocationSize = 1)
public class Board {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE,
                generator = "BOARD_SEQ_GENERATOR")
    private Long id;
}

TABLE 전략 매핑 사용 코드

private static void logic(EntityManger em) {
    Board board = new Board();
    em.persist(board);
    System.out.println("board.id = " + board.getId());
}


// 출력 : board.id = 1
  • MY_SEQUENCES 테이블에 값이 없으면 JPA가 값을 INSERT
  • 미리 넣어둘 필요가 없다.

시퀀스 대신에 테이블을 사용한다는 것만 제외하면 SEQUENCE 전략과 동일

4.6.5 AUTO 전략

GenerationType.AUTO는 선택한 데이터베이스 방언에 따라 INDENTITY, SEQUENCE, TABLE 전략 중 하나를 자동으로 선택.

AUTO 전략 매핑 코드

@Entity
public class Board {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    ...
}

@GeneratedValue.strategy의 기본값은 AUTO.

장점

  • 데이터베이스를 변경해도 코드를 수정할 필요가 없다.
  • 키 생성 전략이 확정되지 않은 개발 초기 단계, 프로토타입 개발시 편리.

4.6.6 기본 키 매핑

테이블의 기본 키 선택 전략 2가지

  • 자연 키
    • 비지니스에 의미가 있는 키
    • 주민등록번호, 이메일, 전화번호
  • 대리 키
    • 비지니스와 관련 없는 임의로 만들어진 키, 대체 키.
    • 오라클 시퀀스, auto_increment, 키생성 테이블

미래까지 충족하는 자연 키를 찾기 쉽지 않다.
JPA는 모든 엔티티에 일관된 방식으로 대리 키 사용을 권장

results matching ""

    No results matching ""