@Basic (opsional = false) vs @Column (nullable = false) di JPA

Jawaban:

98

Gordon Yorke (Anggota Komite Arsitektur EclipseLink, Pimpinan Teknis Inti TopLink, Anggota Kelompok Pakar JPA 2.0) menulis jawaban yang bagus tentang topik ini jadi alih-alih memparafrasekannya, saya akan mengutip jawabannya :

Perbedaan antara optionaldan nullablemerupakan cakupan di mana mereka dievaluasi. Definisi ' optional' berbicara tentang properti dan nilai bidang dan menyarankan bahwa fitur ini harus dievaluasi dalam waktu proses. ' nullable' hanya mengacu pada kolom database.

Jika sebuah implementasi memilih untuk mengimplementasikan optionalmaka properti tersebut harus dievaluasi dalam memori oleh Penyedia Persistensi dan pengecualian yang muncul sebelum SQL dikirim ke database jika tidak ketika menggunakan pelanggaran ' updatable=false' ' optional' tidak akan pernah dilaporkan.

Pascal Thivent
sumber
8
Jadi, mana yang benar-benar harus digunakan, mungkin keduanya?
Xiè Jìléi
39
@Xie Jilei: Dari buku: Java persistence with hibernate 2007, hal. 179: @Basic(optional = false) @Column(nullable = false)Anotasi @Basic menandai properti sebagai bukan opsional pada tingkat objek Java. Pengaturan kedua, nullable = false pada pemetaan kolom, hanya bertanggung jawab untuk pembuatan batasan database NOT NULL. Implementasi Hibernate JPA memperlakukan kedua opsi dengan cara yang sama dalam kasus apa pun, jadi Anda sebaiknya hanya menggunakan salah satu anotasi untuk tujuan ini.
rapt
2
@rapt - Saya tidak mengerti The @Basic annotation marks the property as not optional on the Java object level.Apa artinya? Jadi, @Basicapakah seperti mengatakan bahwa membuat kolom database NOT NULLuntuk variabel tersebut?
Erran Morad
9
Artinya, jika Anda mencoba mempertahankan entitas dengan bidang null, pengecualian akan muncul jika ditandai sebagai opsional = salah (tanpa menghubungi database) dan entitas tidak akan ditambahkan ke konteks persistensi JPA. Jika hanya dianotasi menjadi nullable = false entitas akan ditambahkan ke konteks ketekunan dan ketika mencoba menulis entitas ke database (misalnya melalui flush) itu akan mencoba untuk menulis entitas ke database yang akan menolak ini dan itu akan memunculkan pengecualian.
Ray Hulha
@RayHulha Saya mencoba membuat anotasi bidang dengan "@Basic (opsional = salah)", dan saya menambahkan tupel ke database (dengan nilai bidang ini = null), tidak ada pengecualian yang dimunculkan !!, saya harap Anda dapat menjelaskan bagi saya perilaku ini.
ziMtyth
4

Jadi saya mencoba anotasi @Basic (opsional = false) menggunakan JPA 2.1 (EclipseLink) dan ternyata anotasi tersebut diabaikan dalam penggunaan sebenarnya (setidaknya untuk bidang String). (misalnya panggilan entityManager.persist).

Jadi saya pergi ke spesifikasinya dan membaca tentang itu. Inilah yang dikatakan spesifikasi:
http://download.oracle.com/otndocs/jcp/persistence-2.0-fr-oth-JSpec/

Dasar (opsional): Apakah nilai bidang atau properti boleh nihil. Ini adalah petunjuk dan diabaikan untuk tipe primitif; itu dapat digunakan dalam pembuatan skema.

Jadi saya pikir kalimat ini menjelaskan kasus penggunaan sebenarnya untuk Basic (opsional) yang digunakan dalam pembuatan skema. (Yaitu: ketika Anda membuat CREATE TABLE SQL dari kelas Entitas Java. Ini adalah sesuatu yang dapat dilakukan Hibernate misalnya.)

Ray Hulha
sumber
1
Sangat lucu bahwa jawaban lain menyiratkan bahwa nullable dan bukan Basic yang digunakan untuk pembuatan skema (ketika dikatakan «'nullable' hanya mengacu pada kolom database»). Ini masih sangat membingungkan. Saya kira nullable adalah digunakan untuk skema generasi dan Basic (= opsional palsu) dapat digunakan untuk tujuan yang sama? Apakah itu masuk akal?
marcus
optional = falsehanya untuk memeriksa batasan ini pada waktu proses. nullable = falsemembuat batasan database. Untuk aplikasi, menyetel juga optional = falsemasuk akal, karena dievaluasi lebih cepat daripada membuka database dan memeriksa batasan itu di sana ..
nimo23