Wat een puinhoop... AUTO_INCREMENT
is de verborgen reeks van MySQL. Het radicale probleem is dat MySQL
kan de PK niet tegelijkertijd invoegen en retourneren, maar Hibernate heeft dit nodig terwijl INSERT
een nieuwe entiteit aan.
De problemen die u tegenkomt:
- Als Hibernate een nieuwe Entity opslaat, probeert hij de id automatisch in te stellen op de nieuwe EntityBean. Daarom moet de slaapstand lezen welke ID de database zal gebruiken voordat de slaapstand de nieuwe Tuple opslaat in de tabel.
- Als u meerdere servers heeft die toegang hebben tot de database, moet u de sessiefabriek van de hibernate laten beslissen om de ingebouwde volgorde te gebruiken (AUTO-INCREMENT) of de hibernate laten beslissen (
GenerationType.AUTO
/GenerationType.IDENTITY
) hoe groot het open aanbod van gereserveerde PK's is (Opdracht van een DB-Architect). (We hebben ongeveer 20 servers op één Database, dus op een goed gebruikte tabel gebruiken we een PK-afstand van +100). Als slechts één server toegang heeft tot de databaseGenerationType.TABLE
zal correct zijn.
Hibernate moet de volgende id zelf berekenen met behulp van max(*)+1
maar:
- Wat als twee verzoeken vragen om
max(*)+1
tegelijkertijd/met hetzelfde resultaat? Rechts:de laatste poging ominsert
zal mislukken.
U moet dus een Tabel LAST_IDS
. hebben in de database die de laatste Table-PK's opslaat. Als u er een wilt toevoegen, moet u deze stappen uitvoeren:
- Start leesoptimistische transactie.
- SELECTEER MAX(address_id) FROM LAST_IDS
- het maximum opslaan in een java-variabele, bijv.:$OldID.
- $NewID =$OldID + 1. (+100 in pessimistisch slot)
- UPDATE LAST_IDS SET address_id=
$newID
WHERE address_id=$oldID
? - voer de leesoptimistische transactie uit.
- als de commit succesvol was, bewaar
$newID
naarsetID()
in de HibernateBean die u wilt opslaan. - Laat Hibernate eindelijk de insert aanroepen.
Dit is de enige manier die ik ken.
BTW:Hibernate-Entity's zullen alleen overerving gebruiken als de database overname ondersteunt tussen tabellen zoals PostgreSQL
of Oracle
.