Каква бъркотия... AUTO_INCREMENT
е скритата последователност на MySQL. Радикалният проблем е, че MySQL
не може да вмъкне и върне PK едновременно, но Hibernate се нуждае от това, докато INSERT
въвеждане на нов обект.
Проблемите, с които се сблъсквате:
- Ако Hibernate запази нов Entity, той се опитва да зададе имердентно идентификатора на новия EntityBean. Следователно hibernate трябва да прочете какъв идентификатор ще използва базата данни, преди хибернацията да запише новия кортеж в таблицата.
- Ако имате няколко сървъра, които имат достъп до базата данни, трябва да оставите фабриката за сесии на hibernate да реши да използва вградената последователност (AUTO-INCREMENT) или да оставите hibernate да реши (
GenerationType.AUTO
/GenerationType.IDENTITY
) колко голям е отвореният диапазон от запазени ПК (работа на DB-архитект). (Имаме около 20 сървъра към една база данни, така че на добре използвана маса използваме PK-разстояние от +100). Ако само един сървър има достъп до базата данниGenerationType.TABLE
ще бъде правилно.
Hibernate трябва сами да изчисли следващия идентификатор, като използвате max(*)+1
но:
- Ами ако две заявки поискат
max(*)+1
по едно и също време/със същия резултат? Вдясно:Последният опит заinsert
ще се провали.
Така че трябва да имате таблица LAST_IDS
в базата данни, който съхранява последните Table-PK. Ако искате да добавите такъв, трябва да направите следните стъпки:
- Започнете оптимистична транзакция за четене.
- ИЗБЕРЕТЕ MAX(address_id) ОТ LAST_IDS
- съхранявайте максимума в java-променлива, т.е.:$OldID.
- $NewID =$OldID + 1. (+100 при песимистично заключване)
- АКТУАЛИЗИРАНЕ НА LAST_IDS SET address_id=
$newID
WHERE address_id=$oldID
? - завържете оптимистичната транзакция за четене.
- ако комитирането е било успешно, съхранете
$newID
къмsetID()
в HibernateBean, който искате да запазвате. - Накрая оставете Hibernate да извика вмъкването.
Това е единственият начин, който знам.
BTW:Hibernate-Entitys ще използва наследяване само ако базата данни поддържа наследяване между таблици като PostgreSQL
или Oracle
.