Jaký nepořádek... AUTO_INCREMENT je skrytá sekvence MySQL. Radikální problém je, že MySQL nelze vložit a vrátit PK současně, ale Hibernate to potřebuje, zatímco INSERT vytvoření nové entity.
Problémy, na které narazíte:
- Pokud Hibernate uloží novou entitu, pokusí se nastavit id imerdentelly na novou EntityBean. Proto hibernace musí přečíst, jaké ID bude databáze používat, než hibernace uloží novou n-tice do tabulky.
- Pokud máte více serverů, které přistupují k databázi, musíte nechat továrnu relací hibernace, aby se rozhodla použít vestavěnou sekvenci (AUTO-INCREMENT) nebo nechat rozhodnout hibernaci (
GenerationType.AUTO/GenerationType.IDENTITY) jak velký je otevřený rozsah rezervovaných PK (Job of a DB-Architect). (Máme asi 20 serverů na jednu databázi, takže na dobře používaném stole používáme PK-vzdálenost +100). Pokud má pouze jeden server přístup k databáziGenerationType.TABLEbude správné.
Hibernate musí vypočítat další id sami pomocí max(*)+1 ale:
- Co když dva požadavky požádají o
max(*)+1ve stejnou dobu/se stejným výsledkem? Vpravo:Poslední pokus oinsertselže.
Takže potřebujete mít tabulku LAST_IDS v databázi, kdo ukládá poslední Table-PK's. Pokud chcete jeden přidat, musíte provést tyto kroky:
- Zahajte transakci optimalizovanou pro čtení.
- VYBERTE MAX (ID_adresy) Z LAST_IDS
- uložte maximum do proměnné java, např.:$OldID.
- $NewID =$StaréID + 1. (+100 v pesimistickém zámku)
- UPDATE LAST_IDS SET address_id=
$newIDWHERE address_id=$oldID? - potvrdit transakci optimalizovanou pro čtení.
- pokud bylo potvrzení úspěšné, uložte
$newIDnasetID()v HibernateBean, který chcete uložit. - Nakonec nechejte Hibernate zavolat insert.
Tohle je jediný způsob, jak to vím.
BTW:Hibernate-Entitys použijí dědičnost pouze v případě, že databáze podporuje dědičnost mezi tabulkami jako PostgreSQL nebo Oracle .