Everyday Dev System

GenerationType 종류 본문

내배캠 주요 학습/Spring 숙련

GenerationType 종류

chaeyoung- 2023. 6. 28. 22:14

 

JPA에서 Entity 객체를 정의할 때 반드시 @Id 속성을 정의하여야 한다.

@Id를 정의할 때, 직접 할당, 자동 생성 두가지 방법이 있다.

 

 

 

직접 할당하는 방법

  • @Id 어노테이션을 해당 칼럼 위에 기재

 

    @Id
    private Long id;

 

 

 

자동 생성 방법

 

  • @Id와 @GeneratedValue 어노테이션 해당 칼럼 위에 기재
  • GenerationType의 옵션에는 여러가지가 있다.
  • 사용하는 DB에 의존한다.
    • MySQL은 IDENTITY 사용, Oracle은 SEQUENCE 사용

 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

 

 

 

그 중 가장 많이 활용되는 대표적인 것들을 살펴보자

실무에서는 identity가 가장 많이 쓰인다고 한다.

 

 

 

 

1. GenerationType.IDENTITY

 

기본키 생성을 DB에게 위임한다. (Mysql에서는 Auto_increment를 활용)

서버에서 Id 값을 지정하지 않고 DB에서 SQL문을 실행할 때 Table 내에서 자동으로 증가하여 저장합니다.

 

MySQL과 같이 Sequence를 제공하지 않고, Auto_Increment 기능을 제공해,
기본 키 값을 자동으로 생성하는 DBMS에서 사용한다.

 

 

Hibernate Query문을 보면, 아래과 같이 insert sql문에 아예 id값이 없습니다.

그렇기 때문에 id auto_increment 속성이 들어가 있기에 insert 문에 입력하지 않아도 되는 것입니다.

 


Hibernate: 
    /* insert for
        com.sparta.myblog.entity.User */insert 
    into
        users (password,role,username) 
    values
        (?,?,?)

 

 

 

 

▶ 객체를 저장할 때 벌어지는 일

 

JPA에서 영속성 컨텍스트에서 객체를 관리하기 위해서는 무조건 ID 속성, 즉 PK 값이 있어야 한다.

그렇지만, auto_increment의 경우 서버에서는 그 값이 얼마인지 알지 못한다. DB에 insert 문을 날려야 Id 값을 알 수 있다.

 

 

em.persist()라는 영속성컨텍스트에 저장하는 메서드를 호출하는 즉시 flush()가 이뤄져 영속성 컨텍스트에 저장이 된다기 보단 바로 DB에 Insert 를 하고, 식별자 값을 가져온다. 아직 Transaction을 Commit하지 않았지만 flush()가 이뤄졌기에 Transaction을 지원하는 쓰기 지연 방식이 동작하지 않는다.

 

이렇게 Id 값을 할당한 객체는 영속성 컨텍스트 1차 캐시에 값을 넣게 되는 것이다. 

 

 

즉, IDENTITY 전략은 먼저 Entity를 DB에 저장한 후에 식별자를 
조회해 Entity의 식별자로 할당하는 전략이다.

 

 

 

 

2.GenerationType.SEQUENCE

 

해당 전략은 Sequence 객체가 있는 Oracle, DB2, H2 등에서 사용한다.

DB의 Sequence 객체를 이용해 유일한 값을 순서대로 생성한다.

@SequenceGenerator(시퀀스를 생성하는 어노테이션)과 함께 사용할 수 있다.

 

만약 sequence 객체를 사용하지 않는 DB 벤더를 이용할 경우 Sequence를 관리할 객체(테이블)을 생성한다. 
단, jpa ddl auto 설정이 되어있어야 한다.

 

@Entity
@SequenceGenerator(
	name = "USER_SEQ_GENERATOR"
    , sequenceName = "USER_SEQ"
    , initialValue = 1
    , allocationSize = 1
)
public class User {

    @Id
    @GeneratedValue(
    	strategy = GenerationType.SEQUENCE
    	, generator = "USER_SEQ_GENERATOR"
    )
    private long id;
    
}

 

allocationSize에 설정 값 만큼 한 번에 sequence를 증가 시키고, 그만큼 Memory에 seqeunce 값을 할당한다.

 

 

SEQUENCE 전략은 em.persist() 호출 전에 먼저 DB Sequence를 먼저 조회한다.
그 후 조회한 식별자를 Entity에 할당한 후 Entity를 영속상태로 저장한다.
그 후 Transaction을 Commit하여 Flush가 발생할 때 해당 Entity를 DB에 저장한다.

 

 

 

쓰기 지연이란?

한 트랜잭션안에서 이뤄지는 UPDATE나 SAVE의 쿼리를
쓰기지연 저장소에 가지고 있다가 트랜잭션이 커밋되는 순간 한번에 DB에 날리는 것을 말한다.

IDENTITY는 커밋이 아닌 flush()를 통해 DB에 저장되어 식별자를 서버로 가져오므로, 쓰기 지연 미동작하고,
SEQUENCE는 커밋이 될 때 flush()가 직전에 발생하여 DB에 저장하기때문에 쓰기 지연이 동작 가능하다.

 

 

3. GenerationType.UUID

- 아직 이해가 안가서 더 찾아보고 정리할 예정

 

 

 

 

 

 

 


references : 

https://newwisdom.tistory.com/90

 

[JPA] 기본 키 생성 전략과 각 전략의 차이 - GenerationType

JPA에서 Entity 객체를 정의할 때 @Id 속성을 함께 정의하여야 한다. 이 Id를 정의할 때에는 직접 할당하는 방법과 자동 생성하는 방법이 있다. 직접 할당하는 방법 @Id 어노테이션만으로 id를 지정한

newwisdom.tistory.com

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

 

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

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

velog.io