Dialek PostgreSQL Hibernate tidak terlalu cerah. Itu tidak tahu tentang urutan per-SERIAL Anda, dan mengasumsikan ada urutan database global yang disebut "hibernate_sequence" yang dapat digunakannya.
(PERBARUI :Tampaknya versi Hibernate yang lebih baru dapat menggunakan urutan per tabel default saat GenerationType.IDENTITY
ditentukan. Uji versi Anda dan gunakan ini alih-alih yang di bawah ini jika cocok untuk Anda.)
Anda perlu mengubah pemetaan Anda untuk secara eksplisit menentukan setiap urutan. Itu menjengkelkan, berulang, dan tidak berguna.
@Entity
@Table(name = "JUDGEMENTS")
public class Judgement implements Serializable, Cloneable {
private static final long serialVersionUID = -7049957706738879274L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="judgements_id_seq")
@SequenceGenerator(name="judgements_id_seq", sequenceName="judgements_id_seq", allocationSize=1)
@Column(name = "JUD_ID")
private Long _judId;
...
allocationSize=1
cukup penting. Jika Anda menghilangkannya, Hibernate akan secara membabi buta menganggap bahwa urutannya ditentukan dengan INCREMENT 50
jadi ketika mendapat nilai dari urutan itu dapat menggunakan nilai itu dan 49 nilai di bawahnya sebagai kunci unik yang dihasilkan. Jika urutan database Anda bertambah 1 - default - maka ini akan mengakibatkan pelanggaran unik saat Hibernate mencoba menggunakan kembali kunci yang ada.
Perhatikan bahwa mendapatkan satu kunci pada satu waktu akan menghasilkan perjalanan pulang pergi tambahan per sisipan. Sejauh yang saya tahu Hibernate tidak mampu menggunakan INSERT ... RETURNING
untuk mengembalikan kunci yang dihasilkan secara efisien, juga tampaknya tidak dapat menggunakan antarmuka kunci yang dihasilkan JDBC. Jika Anda menyuruhnya menggunakan urutan, itu akan memanggil nextval
untuk mendapatkan nilai lalu insert
itu secara eksplisit, menghasilkan dua perjalanan pulang pergi. Untuk mengurangi biaya itu, Anda dapat mengatur peningkatan yang lebih besar pada urutan kunci dengan banyak sisipan , mengingat untuk mengaturnya pada pemetaan dan urutan basis data yang mendasarinya. Itu akan menyebabkan Hibernate memanggil nextval
lebih jarang dan blok kunci cache untuk dibagikan saat berjalan.
Saya yakin Anda dapat melihat dari atas bahwa saya tidak setuju dengan pilihan desain Hibernate yang dibuat di sini, setidaknya dari perspektif menggunakannya dengan PostgreSQL. Mereka harus menggunakan getGeneratedKeys
atau menggunakan INSERT ... RETURNING
dengan DEFAULT
untuk kuncinya, biarkan database menangani ini tanpa Hibernate harus merepotkan dirinya sendiri atas nama-nama urutan atau akses eksplisit ke mereka.
BTW, jika Anda menggunakan Hibernate dengan Pg, Anda mungkin juga menginginkan pemicu oplock untuk Pg untuk memungkinkan penguncian optimis Hibernate berinteraksi dengan aman dengan penguncian basis data normal. Tanpa itu atau sesuatu seperti itu, pembaruan Hibernate Anda akan cenderung menggagalkan perubahan yang dibuat melalui klien SQL reguler lainnya. Tanyakan bagaimana saya tahu.