GenerateType.AUTO MYSQL에서 적용 시 주의 할 점

이효진

Updated:

GenerateType.AUTO

스프링부트와 하이버네이트

  • Hibernate 5.0부터는 MYSQL의 AUTO는 IDENTITY가 아닌 TABLE을 기본 시퀀스 전략으로 선택
  • Spring Boot 1.5x -> Hibernate 5.0x 버전 사용
  • Spring Boot 2.0x -> Hibernate 5.2x 버전 사용
  • 스프링 부트는 Hibernate의 ID생성 전략을 따를지 말지 결정하는 useNewIdGeneratorMappings 설정이 존재함

    • spring boot 1.5 : 기본값 false
    • spring boot 2.0 : 기본값 true
  • GenerationType.TABLE : Table sequence 테이블을 두고 모든 테이블의 id를 한 테이블에서 관리


예시

db설정

  datasource:
    url: jdbc:mysql://localhost:3306/board
    username: root
    password: 1234
    driver-class-name: com.mysql.cj.jdbc.Driver

db는 mysql로 설정하였다.

@Entity
public class Board {
	
	@Id @GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	private String title;
	private String content;

테이블 생성

    create table board (
       id bigint not null,
        content varchar(255),
        title varchar(255),
        primary key (id)
    ) engine=InnoDB
2022-01-20 10:11:25.162 DEBUG 26396 --- [  restartedMain] org.hibernate.SQL                        : 
    
    create table hibernate_sequence (
       next_val bigint
    ) engine=InnoDB
2022-01-20 10:11:25.182 DEBUG 26396 --- [  restartedMain] org.hibernate.SQL                        : 
    
    insert into hibernate_sequence values ( 1 )
  • board는 AUTO전략을 사용하므로 시퀀스 테이블이 생성된다.
@Test
	void boardTest() {
		boardRepository.save(new Board("title1","content1"));
		boardRepository.save(new Board("title2","content2"));
	}

결과

Hibernate: 
    select
        next_val as id_val 
    from
        hibernate_sequence for update
            
2022-01-20 11:09:13.425 DEBUG 4076 --- [           main] org.hibernate.SQL                        : 
    update
        hibernate_sequence 
    set
        next_val= ? 
    where
        next_val=?

Hibernate: 
    insert 
    into
        board
        (content, title, id) 
    values
        (?, ?, ?)
  • 위와같이 sequence table에서 id를 받아와서 insert를 실행한다.
  • save 실행 시 id조회해 와서 영속성 컨텍스트에 저장한다.
  • 테이블의 id생성을 auto_increment로 설정해도 테이블에서 조회한다.

해결방법

  1. 하이버네이트의 id생성방식을 따르지 않도록 use-new-id-generator-mappings를 false로 지정한다.
      jpa:
     hibernate:
       ddl-auto: create
       use-new-id-generator-mappings: true
    
  2. generateType.IDENTITY로 설정해준다.
@Entity
public class Board {
	
	@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	private String title;
	private String content;

use-new-id-generator-mapping : false 결과

Hibernate: 
    insert 
    into
        board
        (content, title) 
    values
        (?, ?)

Hibernate: 
    insert 
    into
        board
        (content, title) 
    values
        (?, ?)

아까와는 달리 sequence테이블을 조회하지 않는다.

Leave a comment