관리 메뉴

Rootable의 개발일기

기본 키 생성 전략 본문

JPA

기본 키 생성 전략

dev-rootable 2024. 4. 24. 17:52

출처: https://www.pexels.com/ko-kr/photo/hoppe-115642

 

🚴‍♂️ 기본 키 할당 전략

 

JPA가 제공하는 기본 키 할당 방법은 직접 할당 방식자동 생성 방식이 있다.

 

직접 할당 방식은 애플리케이션에서 기본 키를 직접 할당하는 방식이고, 자동 생성 방식은 DB에 할당을 위임하거나 기본 키를 생성해 주는 별도의 수단을 통해 할당하는 것이다.

 

본 글에서는 직접 할당 방식과 RDBMS에서 많이 사용하는 자동 생성 방식에 대해 다뤄보고자 한다.

 


 

📌 직접 할당 방식

 

Entity를 생성할 때, Key Column에 @Id를 사용하면 된다.

 

@Getter
@Entity
@NoArgsConstructor
public class Member {

    @Id
    private Long id;
    
    ...
    
}

 

해당 전략은 EntityManager.persist()로 Entity를 1차 캐시에 저장하기 전에 애플리케이션에서 직접 기본 키를 할당해 주어야 한다.

 

Member member = Member.builder()
                .id(1)
                .name("kim")
                .build();

 


 

📌 자동 생성 방식

 

자동 생성 방식은 @Id와 @GeneratedValue를 사용한다.

 

@GeneratedValue의 strategy 속성을 통해 4가지 전략을 선택할 수 있다.

 

이 방식은 직접 기본 키를 할당하면 안 된다.

 

🔸 AUTO

 

선택한 DB 방언에 따라 자동으로 IDENTITY, SEQUENCE, TABLE 전략을 자동으로 선택하는 전략

 

  • DB를 변경해도 코드를 수정하지 않아도 되는 장점
  • 키 생성 전략이 정해지지 않은 개발 초기 단계나 프로토타입 개발 시에 편리하게 사용 가능
  • SEQUENCE나 TABLE이 선택될 경우, Sequence나 키 생성 Table을 미리 생성해 두어야 함
    • 만약 DDL 자동 생성 기능을 사용한다면, Hibernate가 기본 값을 사용해 자동으로 생성해 준다.

 

🔸 IDENTITY

 

기본 키 생성을 DB에 위임하는 전략

 

  • MySQL의 경우, AUTO_INCREMENT 기능을 통해 기본 키 제공
  • 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용
  • 지연 쓰기 SQL 저장소를 사용하지 않는다.

 

🔍 AUTO_INCREMENT 동작

JPA는 영속성 컨텍스트라는 1차 캐시에 Entity를 저장(영속)시킨 후에 해당 트랜잭션이 Commit 될 때, 쓰기 지연 저장소에 모아둔 INSERT 쿼리들을 DB에 날린다. 이러한 동기화 작업을 Flush라 한다.

그런데, 1차 캐시에 Entity를 저장하려면 기본 키가 있어야 한다. 하지만 AUTO_INCREMENT는 DB에 기본 키 생성을 위임하기 때문에 INSERT 하기 전에는 기본 키가 없다. 그래서 해당 기능은 영속화하는 시점에 바로 DB에 INSERT 쿼리를 날린다. 결과적으로 쓰기 지연 SQL 저장소를 사용하지 않게 되는 것이다.

 

@Getter
@Entity
@NoArgsConstructor
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "member_id")
    private Long id;

}

 

🔸 SEQUENCE

 

DB의 시퀀스 오브젝트를 사용하여 기본 키를 생성하는 전략

 

  • DB 시퀀스는 유일한 값을 순서대로 생성하는 특별한 DB 오브젝트
  • 주로 Oracle, PostgreSQL, DB2, H2에서 사용
  • @SequenceGenerator를 통해 시퀀스 생성기를 등록할 수 있다.
  • 쓰기 지연 SQL 저장소를 사용한다.

 

🔍 SEQUENCE 동작

Entity를 영속화(persist) 하기 전에 DB 시퀀스를 사용해서 식별자를 조회한다. 그 후에 조회한 식별자를 Entity에
할당한 후에 영속성 컨텍스트에 저장(영속화)한다. 이후 트랜잭션 Commit이나 Flush가 일어나면 실제 DB에 저장하게 된다.

 

@Getter
@Entity
@SequenceGenerator(
        name = "MEMBER_SEQ_GENERATOR",
        sequenceName = "MEMBER_SEQ",
        initialValue = 1, allocationSize = 1
)
@NoArgsConstructor
public class Member extends BaseTimeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
    @Column(name = "member_id")
    private Long id;
    
}

 

✅ 사용 가능한 옵션과 성능 최적화

 

속성 설명 기본 값
name 식별자 생성기 이름 없음 지정 필수
sequenceName DB에 등록되어 있는 시퀀스 이름 hibernate_sequence
initialValue DDL 생성시에만 사용, Sequence DDL 생성시 처음 시작 value를 설정 1
allocationSize 시퀀스 한번 호출 시 증가하는 수(성능 최적화에 사용) 50
catalog, schema DB catalog, schema 이름  

 

allocationSize를 통해 성능 최적화를 할 수 있다.

 

allocationSize에 설정한 값만큼 시퀀스를 가져올 수 있다. 그래서 필요한 만큼 미리 DB에 시퀀스를 올려놓고 식별자로 사용할 수 있어 JPA가 시퀀스에 접근하는 횟수를 줄일 수 있다. 예를 들어 기본 값인 50은 시퀀스를 한번 호출할 때 50개의 식별자로 사용할 값을 준다는 것이다. 해당 값은 서로 겹치지 않도록 DB에서 알아서 조정해 준다.

 

 

🔸 TABLE

 

키 생성 테이블을 사용하여 기본 키를 생성하는 전략

 

  • SEQUENCE 전략과 동작 방식 동일
  • @TableGenerator 필요
  • 값을 조회하면서 Select 쿼리를, 그 후 값 증가를 위해 Update 쿼리를 사용
  • SEQUENCE 전략과 비교하여 DB와 한번 더 통신하므로 성능상 단점
  • SEQUENCE 전략처럼 allocationSize를 통해 최적화할 수 있다.

 

@Entity
@TableGenerator(
        name = "MEMBER_SEQ_GENERATOR",
        table = "MY_SEQUENCES",
        pkColumValue = "MEMBER_SEQ", allocationSize = 1
)
@NoArgsConstructor
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR")
    @Column(name = "member_id")
    private Long id;
    
}

 

✅ Options

 

속성 설명 기본 값
name 식별자 생성기 이름 없음 지정 필수
table 키 생성 테이블 명 hibernate_sequences
pkColumnName 시퀀스 컬럼 명 sequence_name
valueColumnName 시퀀스 값 컬럼 명 next_val
pkColumnValue 키로 사용할 값 이름 Entity 이름
initialValue 초기 값, 마지막 생성된 값이 기준 0
allocationSize 시퀀스 호출 시 증가 값(성능 최적화에 사용) 50
catalog, schema DB catalog, schema 이름  
uniqueConstraints(DDL) 유니크 제약 조건을 지정  

 

References:

 

https://velog.io/@gillog/JPA-%EA%B8%B0%EB%B3%B8-%ED%82%A4-%EC%83%9D%EC%84%B1-%EC%A0%84%EB%9E%B5IDENTITY-SEQUENCE-TABLE#sequence

 

[JPA] 기본 키 생성 전략(IDENTITY, SEQUENCE, TABLE)

자바 ORM 표준 JPA 프로그래밍JPA가 제공하는 DB 기본 키 할당 전략은 직접 할당 방식, 자동 생성 방식 두 가지이다.이 중 직접 할당 방식은 Application에서 기본 키를 직접 할당하는 방식이다.자동 생

velog.io

 

https://www.inflearn.com/course/ORM-JPA-Basic/dashboard

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 | 김영한 - 인프런

김영한 | JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., 실무에서도

www.inflearn.com

 

'JPA' 카테고리의 다른 글

Infinite recursion 에러  (0) 2024.01.21
페치 조인(Fetch join)  (0) 2023.08.21
값 타입 컬렉션(Collection Value Type)  (0) 2023.08.18
임베디드 타입(Embedded Type)  (0) 2023.08.18
값 타입  (0) 2023.08.18