Bagaimana memilih strategi pembuatan id saat menggunakan JPA dan Hibernate

102

Saya telah melalui bagian pembuatan Id dari panduan referensi Hibernate dan "java persistence with Hibernate"

Ada beberapa opsi yang tersedia dengan gabungan Hibernate dan JPA.

Saya sedang mencari dokumentasi lebih lanjut tentang bagaimana memilih strategi pembuatan id tertentu.

Saya juga mencari titik kritis.

Misalnya, strategi hilo diharapkan dapat mengurangi perselisihan. Saya berasumsi pasti ada trade off yang terkait dengan pilihan ini.

Saya ingin dididik tentang trade off.

Apakah ada literatur yang tersedia?

Vlad Mihalcea
sumber

Jawaban:

92

The API Doc sangat jelas tentang hal ini.

Semua generator mengimplementasikan antarmuka org.hibernate.id.IdentifierGenerator. Ini adalah antarmuka yang sangat sederhana. Beberapa aplikasi dapat memilih untuk menyediakan implementasi khusus mereka sendiri, namun Hibernate menyediakan berbagai implementasi bawaan. Nama pintasan untuk generator built-in adalah sebagai berikut:

kenaikan

menghasilkan pengenal tipe panjang, pendek atau int yang unik hanya jika tidak ada proses lain yang memasukkan data ke dalam tabel yang sama. Jangan gunakan di cluster.

identitas

mendukung kolom identitas di DB2, MySQL, MS SQL Server, Sybase dan HypersonicSQL. Pengenal yang dikembalikan berjenis long, short, atau int.

urutan

menggunakan urutan di DB2, PostgreSQL, Oracle, SAP DB, McKoi atau generator di Interbase. Pengenal yang dikembalikan berjenis long, short, atau int

hilo

menggunakan algoritma hi / lo untuk secara efisien menghasilkan pengenal tipe long, short atau int, dengan tabel dan kolom (masing-masing secara default hibernate_unique_key dan next_hi) sebagai sumber nilai hi. Algoritma hi / lo menghasilkan pengenal yang unik hanya untuk database tertentu.

seqhilo.dll

menggunakan algoritma hi / lo untuk secara efisien menghasilkan pengenal tipe panjang, pendek atau int, diberi urutan database bernama.

uuid

menggunakan algoritma UUID 128-bit untuk menghasilkan pengenal tipe string yang unik di dalam jaringan (alamat IP digunakan). UUID dikodekan sebagai string sepanjang 32 digit heksadesimal.

guid

menggunakan string GUID yang dihasilkan database di MS SQL Server dan MySQL.

asli

memilih identitas, urutan atau hilo tergantung pada kemampuan database yang mendasarinya.

ditugaskan

memungkinkan aplikasi menetapkan pengenal ke objek sebelum save () dipanggil. Ini adalah strategi default jika tidak ada elemen yang ditentukan.

Pilih

mengambil kunci utama, yang ditetapkan oleh pemicu database, dengan memilih baris dengan beberapa kunci unik dan mengambil nilai kunci utama.

asing

menggunakan pengenal dari objek terkait lainnya. Biasanya digunakan bersama dengan asosiasi kunci primer.

urutan-identitas

strategi pembuatan urutan khusus yang menggunakan urutan database untuk pembuatan nilai aktual, tetapi menggabungkan ini dengan JDBC3 getGeneratedKeys untuk mengembalikan nilai pengenal yang dihasilkan sebagai bagian dari eksekusi pernyataan penyisipan. Strategi ini hanya didukung pada driver Oracle 10g yang ditargetkan untuk JDK 1.4. Komentar pada pernyataan sisipan ini dinonaktifkan karena bug di driver Oracle.

Jika Anda membangun aplikasi sederhana dengan tidak banyak pengguna bersamaan, Anda dapat menggunakan increment, identity, hilo, dll. Ini mudah dikonfigurasi dan tidak memerlukan banyak coding di dalam db.

Anda harus memilih urutan atau panduan tergantung pada database Anda. Ini aman dan lebih baik karena idpembuatannya akan terjadi di dalam database.

Pembaruan: Baru-baru ini kami memiliki masalah dengan idenditas di mana tipe primitif (int) ini diperbaiki dengan menggunakan tipe warapper (Integer) sebagai gantinya.

ManuPK
sumber
Terima kasih banyak atas tanggapan Anda. Saya sudah melihat dokumennya. Namun, saya mencari mengapa orang menggunakan sesuatu seperti hilo dan seqhilo. Kapan kita membuat pilihan itu. Apa kasus penggunaan untuk memilih.
Ketika ada sesuatu yang sesederhana urutan atau panduan, apa yang dapat mengharuskan pengembang untuk memilih jalan lain.
1
Saya telah memperbarui jawaban saya. Sebenarnya kenaikan, identitas, hilo dll .. lebih sederhana. tetapi tidak cocok untuk aplikasi perusahaan. Mempertahankan semua opsi tidak menjadi masalah, tetapi pastikan Anda menggunakan yang paling sesuai untuk Anda!
ManuPK
Ya. Sejauh ini saya tidak memiliki hak istimewa untuk memberi suara positif atau menerima.
Saya melihat mendalami lebih detail, jika Anda punya waktu, beri tahu saya.
45

Pada dasarnya, Anda memiliki dua pilihan utama:

  • Anda dapat membuat pengenal sendiri, dalam hal ini Anda dapat menggunakan pengenal yang ditetapkan .
  • Anda dapat menggunakan @GeneratedValueanotasi dan Hibernate akan menetapkan pengenal untuk Anda.

Untuk pengenal yang dihasilkan, Anda memiliki dua opsi:

Untuk pengenal numerik Anda memiliki tiga opsi :

  • IDENTITAS
  • URUTAN
  • MEJA

IDENTITAS hanya merupakan pilihan yang baik ketika Anda tidak dapat menggunakan SEQUENCE (misalnya MySQL) karena menonaktifkan pembaruan batch JDBC .

SEQUENCE adalah opsi yang disukai, terutama bila digunakan dengan pengoptimal pengenal seperti pooled atau pooled-lo .

TABLE harus dihindari dengan biaya berapa pun karena TABLE menggunakan transaksi terpisah untuk mengambil pengenal dan kunci tingkat baris yang berskala buruk.

Vlad Mihalcea
sumber
20


Beberapa waktu yang lalu saya menulis artikel rinci tentang generator kunci Hibernate: http://blog.eyallupu.com/2011/01/hibernatejpa-identity-generators.html

Memilih generator yang benar adalah tugas yang rumit, tetapi penting untuk mencoba dan melakukannya dengan benar sesegera mungkin - migrasi yang terlambat mungkin akan menjadi mimpi buruk.

Sedikit keluar dari topik tetapi peluang bagus untuk mengangkat poin yang biasanya terlewatkan yaitu berbagi kunci antar aplikasi (melalui API). Secara pribadi saya selalu lebih suka kunci pengganti dan jika saya perlu mengkomunikasikan objek saya dengan sistem lain, saya tidak mengekspos kunci saya (meskipun itu adalah kunci pengganti) - Saya menggunakan 'kunci eksternal' tambahan. Sebagai konsultan saya telah melihat lebih dari sekali integrasi sistem 'hebat' menggunakan kunci objek (pendekatan 'itu ada di sana mari kita gunakan saja') hanya untuk menemukan satu atau dua tahun kemudian bahwa satu sisi memiliki masalah dengan rentang kunci atau sesuatu dari jenis yang memerlukan migrasi mendalam pada sistem yang mengekspos kunci internalnya. Mengekspos kunci Anda berarti mengekspos aspek fundamental kode Anda ke batasan eksternal seharusnya tidak benar-benar diekspos.

Eyal Lupu
sumber
2

Saya menemukan kuliah ini sangat berharga https://vimeo.com/190275665 , di poin 3 ini merangkum generator ini dan juga memberikan beberapa analisis kinerja dan pedoman saat Anda menggunakan masing-masing.

Adelin
sumber
6
Video itu terlihat sangat familiar.
Vlad Mihalcea