Spring-Boot 2.0. semble avoir modifié la façon dont Hibernate est configuré automatiquement.
Supposons deux entités JPA simples et indépendantes:
@Entity
class Car {
@Id
@GeneratedValue
private long id;
//....
}
@Entity
class Airplane {
@Id
@GeneratedValue
private long id;
//....
}
Auparavant, en utilisant Spring-Boot 1.5.1, je pouvais générer des séquences distinctes d'auto-incréments, ce qui signifie que je peux obtenir un Car
avec 1 comme clé primaire et un Airplane
avec 1 comme clé primaire aussi. Aucune corrélation entre eux, par exemple aucune séquence partagée.
Maintenant, avec 2.0., quand je crée séquentiellement un tout premier Car
puis un tout premier Airplane
, la voiture obtient 1 comme id et avion obtient 2.
Il semble qu'il doive faire face aux GeneratedType.AUTO
, c'est-à-dire "utilisé par défaut" spécifié dans le @GeneratedValue
source d'annotation.
Cependant, mon raisonnement semble s'arrêter là puisque GeneratedType.AUTO
a également été défini par défaut avec 1.5.1.
Une solution simple pour répondre à mes attentes est de spécifier le type de génération de stratégie IDENTITY
comme ceci:
@Entity
class Car {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
//....
}
@Entity
class Airplane {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
//....
}
Je ne peux pas comprendre une explication de ce comportement.
Qu'est-ce que Spring-boot 2.0. a changé, expliquant ce scénario?
Spring Boot 2.0 utilise Hibernate 5.2 ( https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes ).
Hibernate change son GeneratedType.AUTO
stratégie depuis 5.2. Toute base de données qui ne prend pas en charge les séquences nativement (par exemple MySQL), elles utilisent le générateur TABLE au lieu d'IDENTITY. ( https://hibernate.atlassian.net/browse/HHH-11014 )
Voilà pourquoi GeneratedType.AUTO
ne fonctionne pas comme prévu.
Comme Andrew l'a souligné dans le commentaire, si vous ne voulez pas que l'ID soit incrémenté pendant que les valeurs sont créées dans d'autres tables, vous pouvez spécifier votre ID comme ceci:
@Id
@GeneratedValue(
strategy= GenerationType.AUTO,
generator="native"
)
@GenericGenerator(
name = "native",
strategy = "native"
)
private Long id;
En faisant cela, chaque table aura son identifiant unique commençant par 1,2,3 ... et ainsi de suite.
Si vous avez besoin d'une solution rapide et non évolutive pour éviter ce problème:
spring.jpa.hibernate.use-new-id-generator-mappings=false
, à partir des documents Spring Boot 2:
spring.jpa.hibernate.use-new-id-generator-mappings= # Whether to use Hibernate's newer IdentifierGenerator for AUTO, TABLE and SEQUENCE.
Cela empêchera d'utiliser les nouveaux générateurs et conservera les anciennes fonctionnalités incluses dans Spring boot 1.x.x.
Veuillez noter que ce n'est probablement pas la meilleure solution, mais c'est très utile à court terme