Che casino... AUTO_INCREMENT è la sequenza nascosta di MySQL. Il problema radicale è che MySQL non può inserire e restituire il PK allo stesso tempo, ma Hibernate ne ha bisogno mentre INSERT ing una nuova entità.
I problemi che incontri:
- Se Hibernate salva una nuova Entity, prova a impostare in modo immersivo l'id sul nuovo EntityBean. Pertanto l'ibernazione deve leggere quale ID utilizzerà il database prima che l'ibernazione salvi la nuova tupla nella tabella.
- Se hai più server che accedono al database, lascerai che la session-factory di Hibernate decida di usare la sequenza incorporata (AUTO-INCREMENT) o lasci che Hibernate decida (
GenerationType.AUTO/GenerationType.IDENTITY) quanto è grande l'intervallo aperto di PK riservati (Job of a DB-Architect). (Abbiamo circa 20 server in un database, quindi su una tabella ben utilizzata utilizziamo una distanza PK di +100). Se solo un server ha accesso al databaseGenerationType.TABLEdeve essere corretto.
Hibernate deve calcolare da solo l'ID successivo utilizzando max(*)+1 ma:
- Cosa succede se due richieste richiedono
max(*)+1contemporaneamente/con lo stesso risultato? A destra:l'ultimo tentativo diinsertavrà esito negativo.
Quindi devi avere una tabella LAST_IDS nel database che memorizza gli ultimi Table-PK. Se desideri aggiungerne uno, devi eseguire questi passaggi:
- Avvia transazione con ottimismo in lettura.
- SELECT MAX(address_id) DA LAST_IDS
- Memorizza il massimo in una variabile java, ad esempio:$OldID.
- $NewID =$OldID + 1. (+100 in blocco pessimistico)
- UPDATE LAST_IDS SET address_id=
$newIDDOVE address_id=$oldID? - commenta la transazione di lettura ottimistica.
- se il commit è andato a buon fine, memorizza
$newIDasetID()nell'HibernateBean che desideri salvare. - Finalmente lascia che Hibernate chiami l'inserto.
Questo è l'unico modo che conosco.
A proposito:Hibernate-Entity utilizzerà l'ereditarietà solo se il database supporta l'ereditarietà tra tabelle come PostgreSQL o Oracle .