Spring Boot 2 アップグレード後に JPA ( Hibernate )が勝手に SEQUENCE を使おうとする問題

問題

Spring Boot 1.5 -> 2.0 に上げたとき MySQLJPAHibernate)経由で利用している場合、 GeneratedValue に AUTO を指定していると INSERT 処理時などに下記のような例外が発生する可能性がある。

Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException Table 'xxx.hibernate_sequence' doesn't exist

原因

Spring Boot の AutoConfiguration では hibernate を使う際に hibernate.id.new_generator_mappings の値のデフォルト値が false になっており、native の id generator が使われていたが Spring Boot 2 になったタイミングでデフォルト値が true になった。 hibernate.id.new_generator_mappings が true の場合、Hibernate 5 では AUTO が指定された場合は常に SEQUENCE 扱いとなる様子。MySQL の場合は SEQUENCE に対応していないため AUTO にしている状態では動かなくなる。

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide

Id generator

The spring.jpa.hibernate.use-new-id-generator-mappings property is now true by default to align with the default behaviour of Hibernate. If you need to temporarily restore this now deprecated behaviour, set the property to false.

Spring Boot 1.5

https://github.com/spring-projects/spring-boot/blob/v1.5.14.RELEASE/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java#L207

        result.put(USE_NEW_ID_GENERATOR_MAPPINGS, "false");

Spring Boot 2.0

https://github.com/spring-projects/spring-boot/blob/v2.0.3.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaProperties.java#L237

        result.put(USE_NEW_ID_GENERATOR_MAPPINGS, "true");

対応案

下記2つの対応が考えられる

  • spring.jpa.hibernate.use-new-id-generator-mappings の設定を 明示的に false を使う
  • 対象となる GeneratetedValue アノテーションすべてに明示的に IDENTITY を指定する

id generator が false は deprecated とあるので true のほうがよさそうだが デフォルトの AUTO のままでは IDENTITY が使われるルートがなさそうなので一括で対応する方法はなさそう。

参考 URL