1. 기본키매핑에는 어떤 애노테이션을 사용하는가?
기본키 매핑에는 @Id, @GeneratedValue 를 사용할 수 있다. 기본키를 생성하는 방법은 직접 값을 지정하는 방법과, auto-increment, sequence 생성들을 통해 자동으로 방법등 여러가지가 있는데 크게 직접할당과 자동 생성으로 나눌 수 있다.
1) 직접 할당 : @Id 만을 사용한다.
@Id
private Long id;
2) 동적 할당 : @Id 와 @GeneratedValue 를 동시에 사용한다.
@Id
@GeneratedValue
private Long id;
여기서 자동생성 하는 방법에서 총 네가지의 strategy 를 선택할 수 있다.
2. 기본키 매핑시 @GeneratedValue 에 지정할 수 있는 strategy 종류
1) IDENTITY : 데이터베이스에 위임 한다 . 예를들어, mysql 같은 경우 auto-increment 를 사용하는 경우에 사용하면 된다.
2) SEQUENCE : 데이터베이스에서 제공하는 시퀀스 오브젝트를 사용한다. 시퀀스를 통해 기본 키를 지정하는 것을 의미하는데,
이때 @SequenceGenerator 라는 애노테이션이 추가적으로 필요하다.
@Entity
@SequenceGenerator(name = "member_seq_generator", sequenceName = "member_seq")
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_seq_generator")
private Long id;
}
위 예시에서 보면 @SequenceGenerator 애노테이션을 클래스에 추가하고 name, sequenceName 값을 추가 하였다.
여기서 name 은 @GeneratedValue 의 generator 의 값에 맞춰 줘야 한다.
sequenceName 값은 실제 db 에 생성되는 시퀀스의 이름을 의미한다.
위 예시 코드를 실행 할 경우 실제 db 에 요청 되는 생성문은 아래와 같다.
Hibernate: create sequence member_seq start with 1 increment by 50
@SequenceGenerator 기본값
|
||
name
|
식별자 생성기 이름
|
필수
|
sequenceName
|
데이터베이스에 등록되어 있는 시퀀스 이름
|
hibernate_sequence
|
initialValue
|
DDL 생성 시에만 사용됨, 시퀀스 DDL을 생성할 때 처음 1 시작하는 수를 지정한다.
|
1
|
allocationSize
|
시퀀스 한 번 호출에 증가하는 수(성능 최적화에 사용됨 데이터베이스 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 이 값 을 반드시 1로 설정해야 한다
|
50
|
catalog, schema
|
데이터베이스 catalog, schema 이름
|
3) TABLE : 키를 생성하기 위한 테이블을 별도로 주는 전략(strategy) 이다. 모든 DB 에서 사용하지만 자주 사용하지 않는다.
추가적으로 @TableGenerater 애노테이션이 필요하다.
4) AUTO : 방언에 따라 자동 지정하는 것을 의미한다. 즉 데이터베이스의 설정을 따라간다. strategy 의 기본값이다.
3. 영속성을 줄 때 (persist 할 때 ) 시퀀스의 호출 순서 와 유의점
이전에 정리한 내용에서는, persist 한다고 바로 db 에 반영도는 것이 아니라 영속성 컨텍스트에 올라간다고 정리했다.
그런데 시퀀스의 경우, commit 하지 않아도 예외적으로 먼저 호출 된다. 왜일까?
엔티티별로 매핑될 키 값은 반드시 필요한 요소기 때문이다. 추가적으로, 기본키(PK) 를 시퀀스로 지정했을 경우에는
기본키가(PK) 엔티티 생성시 자동으로 지정되기 ( 시퀀스가 자동으로 호출) 때문에 기본키(PK)에 해당하는 값은 제외하고 엔티티를 생성해야 한다.
- 잘못 된 예시
// 생성자
public Member(Long id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
// 엔티티 생성
Member tm = new Member(1, "name1", 10);
em.persist(tm);
- 올바른 예시
//생성자
public Member(String name, int age) {
this.name = name;
this.age = age;
}
// 엔티티 생성
Member tm = new Member("name1", 10);
em.persist(tm);
4. 기본키는 어떻게 지정하면 좋을까?
실무에서는 기본키를 지정할 때 Long형 + 대체키 + 키 생성 전략을 함께 쓰는 것이 권장 된다.
출처 : JAVA ORM 표준 JPA 프로그래밍
'Dev > JPA' 카테고리의 다른 글
JPA 상속관계 매핑 - 상속 전략과 MappedSuperClass (0) | 2023.12.27 |
---|---|
JPA 에서 연관관계의 정의 (1) | 2023.12.27 |
JPA 에서 데이터베이스 스키마 자동생성 기능 사용하기 (0) | 2023.12.11 |
JPA 에서 영속성의 의미와 사용하는 애노테이션 정리 (0) | 2023.12.11 |
h2 초기 연결시 JdbcSQLNonTransientConnectionException 에러 해결 방법 (0) | 2023.12.06 |