Maison > Article > base de données > Pourquoi l'utilisation de @GeneratedValue(strategy = GenerationType.TABLE) avec une superclasse abstraite provoque-t-elle des problèmes dans une application Spring avec Hibernate et MySQL ?
@GeneratedValue Pièges avec Abstract Superclass et MySQL
Dans une tentative de gérer les valeurs d'ID dans une application Spring avec Hibernate et MySQL, en utilisant un la superclasse abstraite BaseEntity peut entraîner des défis. Lorsque @GeneratedValue(strategy = GenerationType.TABLE) est utilisé, une erreur survient en raison de l'absence d'une table hibernate_sequences requise par Hibernate pour générer des identifiants de manière incrémentielle.
Le problème sous-jacent
MySQL ne supporte pas nativement les séquences, ce qui constitue un obstacle pour l'approche GenerationType.TABLE. Cette stratégie utilise généralement une table dédiée pour suivre les valeurs de séquence et attribuer des identifiants uniques. Comme MySQL ne dispose pas de cette fonctionnalité, cela entraîne l'erreur « La table 'docbd.hibernate_sequences' n'existe pas ».
Résoudre le problème
Pour surmonter ce problème et conserver les objets avec succès, une solution de contournement est nécessaire :
1. Utilisez GenerationType.IDENTITY
Cette stratégie repose sur le propre mécanisme d'incrémentation automatique de la base de données, qui élimine le besoin d'une table de séquence dédiée. Cependant, cela est incompatible avec l'intention d'utiliser une superclasse abstraite pour gérer les identifiants entre les classes dérivées.
2. Créer une table de séquence Hibernate
Malgré le manque de prise en charge native des séquences par MySQL, il permet la création de tables personnalisées pour émuler le comportement des séquences. Voici un exemple de création d'une telle table nommée hibernate_sequences :
CREATE TABLE IF NOT EXISTS hibernate_sequences( sequence_name VARCHAR(255) NOT NULL, sequence_next_hi_value INT UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (sequence_name) ) ENGINE=InnoDB;
3. Configurez Hibernate pour utiliser la séquence personnalisée
Dans la classe BaseEntity, ajustez l'annotation @GeneratedValue pour utiliser la table de séquence personnalisée :
@GeneratedValue(strategy = GenerationType.TABLE, generator = "hilo_generator") private Integer id; @SequenceGenerator(name = "hilo_generator", sequenceName = "hibernate_sequences", allocationSize = 1)
4. Ajuster la définition de colonne dans la table d'entités
Dans la table CCD, assurez-vous que la définition de la colonne id correspond à la séquence personnalisée :
CREATE TABLE IF NOT EXISTS ccd( id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, #other stuff ) ENGINE=InnoDB;
Méthode de secours
En dernier recours, si l'approche de séquence personnalisée échoue en raison d'autres problèmes inattendus, envisagez d'implémenter un mécanisme de génération manuelle d'ID dans BaseEntity. class :
private static int idSequence = 0; public Integer getId() { if (id == null) { return idSequence++; } return id; }
Conclusion
L'utilisation d'une superclasse abstraite pour la gestion des identifiants dans une application Spring avec Hibernate et MySQL nécessite un examen attentif des limitations sous-jacentes de la base de données. Utiliser la solution de contournement consistant à créer une table de séquence personnalisée peut atténuer le problème résultant du manque de prise en charge native des séquences par MySQL. Cependant, ces approches peuvent avoir des implications sur les performances ou introduire une complexité supplémentaire dans la conception du système.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!