Sungguh kacau... AUTO_INCREMENT
adalah urutan tersembunyi MySQL. Masalah radikalnya adalah MySQL
tidak dapat memasukkan dan mengembalikan PK secara bersamaan, tetapi Hibernate membutuhkan ini saat INSERT
ing Entitas baru.
Masalah yang Anda hadapi:
- Jika Hibernate menyimpan Entitas baru, ia mencoba untuk segera menyetel id ke EntityBean baru. Oleh karena itu hibernasi harus membaca ID apa yang akan digunakan Database sebelum hibernasi menyimpan Tuple baru ke Tabel.
- Jika Anda memiliki beberapa Server yang mengakses database, Anda harus membiarkan session-factory hibernate memutuskan untuk menggunakan urutan bawaan (AUTO-INCREMENT) atau membiarkan hibernate memutuskan (
GenerationType.AUTO
/GenerationType.IDENTITY
) seberapa besar rentang terbuka PK yang dicadangkan (Pekerjaan Arsitek DB). (Kami memiliki sekitar 20 server untuk satu Database, jadi pada tabel yang digunakan dengan baik kami menggunakan jarak PK +100). Jika hanya satu server yang memiliki akses ke databaseGenerationType.TABLE
harus benar.
Hibernate harus menghitung sendiri id berikutnya menggunakan max(*)+1
tapi:
- Bagaimana jika dua permintaan meminta
max(*)+1
pada saat yang sama/dengan hasil yang sama? Kanan:Percobaan terakhir untukinsert
akan gagal.
Jadi, Anda perlu memiliki Tabel LAST_IDS
dalam database yang menyimpan Tabel-PK terakhir. Jika Anda ingin menambahkannya, Anda harus melakukan langkah-langkah ini:
- Mulai transaksi read-optimistic.
- PILIH MAX(address_id) DARI LAST_IDS
- menyimpan maksimum dalam variabel java yaitu:$OldID.
- $NewID =$OldID + 1. (+100 dalam kunci pesimistis)
- PERBARUI LAST_IDS SET address_id=
$newID
WHERE address_id=$oldID
? - melakukan transaksi read-optimistic.
- jika komit berhasil, simpan
$newID
kesetID()
di HibernateBean yang ingin Anda simpan. - Akhirnya biarkan Hibernate memanggil sisipan.
Ini satu-satunya cara yang saya tahu.
BTW:Hibernate-Entitys hanya akan menggunakan pewarisan jika Database mendukung pewarisan antar tabel seperti PostgreSQL
atau Oracle
.