Mysql
 sql >> Base de données >  >> RDS >> Mysql

@GeneratedValue superclasse abstraite polymorphe sur MySQL

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 :

  1. 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.
  2. 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ées GenerationType.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 :

  1. Démarrer une transaction optimiste en lecture.
  2. SELECT MAX(address_id) FROM LAST_IDS
  3. stocker le maximum dans une variable Java, c'est-à-dire :$OldID.
  4. $NewID =$OldID + 1. (+100 en verrouillage pessimiste)
  5. UPDATE LAST_IDS SET address_id=$newID WHERE address_id=$oldID ?
  6. valider la transaction read-optimistic.
  7. si la validation a réussi, stockez $newID à setID() dans le HibernateBean que vous souhaitez enregistrer.
  8. 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 .