자동생성 전략
- IDENTITY: 데이터베이스에 위임, MYSQL
- SEQUENCE: 데이터베이스 시퀀스 오브젝트 사용, ORACLE
- @SequenceGenerator 필요
- TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용
- @TableGenerator 필요
- AUTO: 방언에 따라 자동 지정, 기본값
보통 JPA는 em.commit() 시점에 insert sql
하지만 영속성 컨텍스트에 엔티티 정보를 넣으려면 반드시 PK가 필요
때문에 IDENTITY 전략에서만 persist 시점에 데이터베이스에 저장하여 PK를 가져옴
일반적인 지연 쓰기가 불가능
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
try {
Member4 member = new Member4();
member.setUsername("hello world");
System.out.println("====================");
em.persist(member); //insert 쿼리
System.out.println("member.username = " + member.getUsername());
System.out.println("====================");
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
@SequenceGenerator(
name = "MEMBER_SEQ_GENERATOR",
sequenceName = "MEMBER_SEQ", //맵핑할 데이터베이스 시퀀스 이름
initialValue = 1, allocationSize = 1)
//allocationSize 기본값은 50
//DB에서 미리 가져와서 메모리에 올려놓고 씀 => 네트워크 왔다갔다하는 성능 이슈 해결
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
private Long id; //Integer보다 Long 사용 권장
try {
Member4 member = new Member4();
member.setUsername("hello world");
System.out.println("====================");
em.persist(member);
//영속성 컨텍스트에 엔티티를 관리하려면 PK가 필요
//@GeneratedValue(strategy = GenerationType.SEQUENCE)인 경우에는
//persist하는 시점에 seq 조회 쿼리 후 영속성 컨텍스트에 넣어둠
//데이터베이스에 저장하지는 않으며 지연 쓰기 가능
System.out.println("member.username = " + member.getUsername());
System.out.println("====================");
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
권장하는 식별자 전략
- 기본 키 제약 조건: null 아님, 유일, 변하면 안된다.
- 미래까지 이 조건을 만족하는 자연키는 찾기 어렵다. 대리키(대
체키)를 사용하자.- 예를 들어 주민등록번호도 기본 키로 적절하기 않다.
- 권장: Long형 + 대체키 + 키 생성전략 사용