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.TABLE
deve essere corretto.
Hibernate deve calcolare da solo l'ID successivo utilizzando max(*)+1
ma:
- Cosa succede se due richieste richiedono
max(*)+1
contemporaneamente/con lo stesso risultato? A destra:l'ultimo tentativo diinsert
avrà 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=
$newID
DOVE address_id=$oldID
? - commenta la transazione di lettura ottimistica.
- se il commit è andato a buon fine, memorizza
$newID
asetID()
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
.