Quel gâchis... AUTO_INCREMENT
est la séquence cachée de MySQL. Le problème radical est que MySQL
ne peut pas insérer et renvoyer le PK en même temps, mais Hibernate en a besoin pendant que INSERT
créer une nouvelle entité.
Les problèmes que vous rencontrez :
- Si Hibernate enregistre une nouvelle entité, il essaie de définir immédiatement l'identifiant sur le nouvel EntityBean. Par conséquent, hibernate doit lire quel ID la base de données utilisera avant que hibernate enregistre le nouveau tuple dans la table.
- Si vous avez plusieurs serveurs qui accèdent à la base de données, vous devez laisser la session-factory d'hibernate décider d'utiliser la séquence intégrée (AUTO-INCREMENT) ou laisser hibernate décider (
GenerationType.AUTO
/GenerationType.IDENTITY
) quelle est la taille de la plage ouverte de PK réservés (Travail d'un architecte de base de données). (Nous avons environ 20 serveurs pour une base de données, donc sur une table bien utilisée, nous utilisons une distance PK de +100). Si un seul serveur a accès à la base de donnéesGenerationType.TABLE
doit être correct.
Hibernate doit calculer le prochain identifiant par vous-même en utilisant max(*)+1
mais :
- Et si deux requêtes demandent
max(*)+1
en même temps/avec le même résultat ? À droite :la dernière tentative d'insert
échouera.
Vous devez donc avoir une table LAST_IDS
dans la base de données qui stocke les dernières Table-PK. Si vous souhaitez en ajouter un, vous devez suivre ces étapes :
- Démarrer une transaction optimiste en lecture.
- SELECT MAX(address_id) FROM LAST_IDS
- stocker le maximum dans une variable Java, c'est-à-dire :$OldID.
- $NewID =$OldID + 1. (+100 en verrouillage pessimiste)
- UPDATE LAST_IDS SET address_id=
$newID
WHERE address_id=$oldID
? - valider la transaction read-optimistic.
- si la validation a réussi, stockez
$newID
àsetID()
dans le HibernateBean que vous souhaitez enregistrer. - Enfin, laissez Hibernate appeler l'insert.
C'est le seul moyen que je connaisse.
BTW :Hibernate-Entitys ne doit utiliser l'héritage que si la base de données prend en charge l'héritage entre des tables comme PostgreSQL
ou Oracle
.