IT/데이터베이스

[Java/Hibernate] PK 전략방식 그리고 안됐던 내용 정리

홀롤록 2023. 10. 18. 09:03
반응형

안녕하세요. 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 전략과 흡사하고, 내부동작 또한 같습니다, 시퀀스 대신 테이블을 사용하는 것만 다릅니다.

반응형