Try   HackMD

JPA 자동키 생성전략 GenerationType.AUTO

GenerationType 종류

키 생성전략을 @Entity 에서 정의할수 있는데 종류는 다음과 같다.

  • AUTO
  • TABLE
  • SEQUENCE
  • IDENTITY

Entity 에서 아무것도 설정하지 않으면 AUTO 이다.

GenerationType.AUTO 동작 메커니즘

AUTO 가 까다로운데 popit 유영모님 글 을 보고 정리가 되었다.
특히 아래 이미지는 대박!

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

AUTO 설정시 하이버네이트가 자동으로 생성 전략을 결정한다.
이때 몇가지 변수들을 참조해서 결정하는데 대표적으로 다음과 같다.

  1. java 타입이 무엇 인지
  2. id_new_generator_mappings 가 true 인지
  3. false면 native generator 를 따르는데 방언이 있는지 등을 살펴본다.

나는 Mysql 의 Auto_increament 를 쓰고싶다!

일일이 GenerationType.IDENTITY 를 설정할게 아니라면 생략 가능한 AUTO 를 써야하고, AUTO를 쓰면서도 IDENTITY로 배정받을수 있게 해야한다. 어떻게하면 좋을까?

GenerationType.AUTO 로 설정하고 IDENTITY 배정받기

위 그림을 보고 잘 드리블 해보자.

  1. DataType이 UUID가 아니어야하고 (어짜피 Long 일테니 큰상관 없다)
  2. 하이버네이트 아이디 제네레이터를 꺼야 하고.

spring.jpa.hibernate.use-new-id-generator-mappings=false

  1. native generator 가 참고할수있게 다이얼렉트가 설정 되어있어야 한다.

spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

그냥 자동 배정해주는 TABLE 쓰면 안될까?

위의 이미지에서 use-new-id-generator-mappings=true 설정 되어 있고, sequence generator 가 동작하지 않으면 table generator 로 간다고 했다.

use-new-id-generator-mappings는 기본값이 true이니 생략해도 되고, Mysql은 sequence generator 가 동작하지 않으니 별다른 설정을 하지 않으면 TABLE 전략을 택하게 된다.

TABLE은 설정도 간편한데다 장점이 많다. 장점을 정리해 보면,

  1. 별다른 설정을 안해도 됨
  2. 쓰기지연 가능 (auto_increament는 쓰기지연을 쓸수없다)
  3. 벤더를 바꿀때도 유연함
  4. 그간의 경험상 스탠다드 설정은 호환도 좋고 예제도 좋고 여러모로 이점이 많다

많은 장점 때문에 TABLE 전략으로 굳히려 했으나.
다수의 스레드로 동시 접근 일수록 병목 현상이 발견 된다는 글을 발견했다.
https://vladmihalcea.com/why-you-should-never-use-the-table-identifier-generator-with-jpa-and-hibernate/

4개 스레드 까지는 차이가 없으나, 8개 스레드 부터는 거의 2배 가까이 느리다고 한다.
allocation size 를 500~1000 정도 주면 문제없다는 이의제기를 하는 댓글도 있지만 답글에는 본인이 작성한 책을 보면 알수있다 정도로 마무리를 하는것 같다.