@Id
- 직접 Id값을 할당할때 사용
Member member = new Member();
member.setId("ID_A);
@GeneratedValue
속성
- IDENTITY
사용법 >> @GeneratedValue(strategy = GenerationType.IDENTITY)
데이터베이스에게 값의 생성을 위임하며, 대표적으로 MYSQL의 AUTO_INCREMENT가 있다
IDENTITY는 String 타입의 필드도 가능하지만 SEQUENCE는 문자열 타입 불가능
IDENTITY전략으로 ID값을 생성시 해당 ID값을 알 수 있는 시기는 DB에 저장된 시점이다. 하지만 영속성 컨텍스트에서 관리되기 위해서는 PK값이 필요한데 DB에 저장되기 전에는 ID값이 존재하지 않게된다. 이를 해결하기 위해 보통 Transaction.commit()시기에 INSERT문이 DB에 보내지는데 IDENTITY 전략은 em.persist()시점에 INSERT문이 바로 DB에 보내진다.
- SEQUENCE
DB의 시퀀스 Object를 사용(@SequenceGenerator 필요)하며, 대표적으로 ORACLE 의 오라클 시퀀스가 있다.
IDENTITY는 String 타입의 필드도 가능하지만 SEQUENCE는 문자열 타입 불가능
@Entity
@SequenceGenerator(
name = "MEMBER_SEQ_GENERATOR",
sequenceName = "MEMBER_SEQUENCE", //매핑할 DB 시퀀스 이름
initialValue = 1, allocationSize = 1)
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "MEMBER_SEQUENCE")
private Long id;
위와같이 @SequenceGenerator를 사용하면 각 테이블마다 sequence를 따로 관리할 수 있다.
SEQUENCE전략도 IDENTITY와 마찬가지로 DB에 저장된 시점에 ID값을 알 수 있는데, SEQUENCE전략은 em.persist()시점에 DB에게 해당 시퀀스의 다음 값을 가져오라고 해서 다음 값을 ID에 넣어주게 된다.(이전 ID값이 1이었으면 다음인 2값이 ID에 저장) IDENTITY와 다른점은 ID값만 불러온 다음 영속성 컨텍스트에 계속 쌓아두다 INSERT쿼리를 Transaction.commit() 시점에 한다는 것이다.(버퍼링 가능) 다만 어쨌든 ID값을 DB에서 가져오기 떄문에 성능이슈가 발생할 수 있는데 이를 allocationSize를 사용함으로써 해결할 수 있다.
예를들어 allocationSize = 50 으로 설정한다면(default값이 50) 1부터 50까지의 ID값을 미리 DB에 생성후 em.persist()시에 1부터 50까지 가져오게 되는데 50까지 가져왔으므로 다음 em.persist()를 다시 해도 DB에서 값을 호출하는것이 아닌 메모리상에서 다음값을 ID에 할당하게 된다.
- TABLE
키 생성 전용 테이블을 만들어서 DB sequence를 흉내내는 전략으로 모든 DB에 적용이 가능하지만 성능의 이슈가 있다.
잘 쓰이지 않는 전략이다.
- AUTO : 방언에 따라 자동으로 지정해준다.
'스프링' 카테고리의 다른 글
[스프링] 즉시로딩과 지연로딩 (0) | 2023.02.10 |
---|---|
[스프링] 프록시란 (0) | 2023.02.10 |
[스프링] 필드와 컬럼 매핑 Annotation (0) | 2023.02.09 |
[스프링] 영속성 컨텍스트란 (0) | 2023.02.09 |
JPA(Java Persistance API)란 (0) | 2023.02.06 |