안녕하세요. spring + H2 DB를 가볍게 사용하여 회사 내부에 사이드 프로젝트를 진행하고 있습니다.
기능을 만들고 이제 데이터를 넣어보자! 하는 상황에서 발생한 문제점입니다.
현재 H2 DB 2.1.214 버전을 사용하고 있는데 PK 전략이 정상적으로 동작하지 않는 것 같았으나
알고보니 단순히 제가 다른 구성컬럼에 유니크 속성을 걸어둔 문제였습니다..
이 기회에 작성해두는 PK 전략방식!
# IDENTITY 전략
@Id
@GerneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;
IDENTITY 전략은 기본 키 생성을 데이터베이스에 위임하는 전략입니다.
이 전략은 주로 MySQL, PostgreSQL, SQL Server 에서 사용합니다.
단적인 예로 MySQL 에 있는 AUTO_INCREMENT 처럼 데이터베이스에 값을 저장하고 후에 기본 키 값을 구할 수 있을 때 사용합니다.
이를 사용할 때의 주의할 점은 식별자를 DB에서 지정 전까지는 알 수 없습니다.
em.persist() 를 할 때 즉시 INSERT 문이 데이터베이스에 전달되기 떄문에 트랜잭션을 지원하는 쓰기 지연이 동작하지 않습니다.
@Entity
@SequenceGenerator(
name = "SEQ_GENERATOR",
sequenceName = "TEST_SEQ",
initialValue = 1, allocationSize = 1
)
public class SequenceEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_GENERATOR")
private Long id;
}
# 시퀀스 전략
DB 에서의 Sequence 오브젝트를 사용해 순서대로 값을 생성하는 기능을 사용하여 기본 키를 생성합니다.
이 전략은 시퀀스를 지원하는 DB에서 사용할 수 있으며, Oracle, PostgreSQL, H2 DB 에서 사용합니다.
시퀀스 전략을 사용하려면 사용할 데이터베이스 시퀀스를 매핑하여야 합니다.
소스에 @SequenceGenerator 를 사용해 시퀀스를 생성하고, @GeneratedValue > generator 속성으로 시퀀스를 선택했습니다.
이는 IDENTITY 와는 달리 시퀀스 전략은 em.persist()를 호출할 때 먼저 데이터베이스 시퀀스를 통해 식별자를 조회하고 조회된 식별자를 Entity에 할당하여 영속성 컨텍스트에 저장합니다.
그리고 난 후 트랜잭션 커밋 시점에서 flush 가 발생하게 되면 DB에 Entity 를 저장하는 방식입니다.
@Entity
@TableGenerator(
name = "TEST_SEQ_GENERATOR",
table = "TEST_SEQUENCE",
pkColumnValue = "TEST_SEQ",
initialValue = 1,
allocationSize = 50
)
public class TableEntity {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "TEST_SEQ_GENERATOR")
private Long id;
}
# 테이블 전략
이는 키 생성 테이블을 하나 만들어 데이터베이스 시퀀스 흉내를 내는 전략입니다. 시쿠너스를 지원하지 않는 DB에서도 사용이 가능합니다.
전략내용은 SEQUECE 전략과 흡사하고, 내부동작 또한 같습니다, 시퀀스 대신 테이블을 사용하는 것만 다릅니다.
'IT > 데이터베이스' 카테고리의 다른 글
[RDS/MySQL] AWS Aurora 를 쓰는데 종종 개발서버 Latency가 길어진다!? (0) | 2021.05.17 |
---|---|
[RDB/MySQL] 이모지를 사용하는 DB Charset 설정 (0) | 2021.05.07 |
터미널 버전 Redis 설치하기 (0) | 2021.04.01 |