Apakah mungkin untuk menetapkan nilai default untuk kolom di JPA, dan jika, bagaimana cara menggunakan anotasi?
java
jpa
annotations
homaxto
sumber
sumber
Jawaban:
Sebenarnya ini dimungkinkan di JPA, walaupun sedikit peretasan menggunakan
columnDefinition
properti@Column
anotasi, misalnya:sumber
insertable=false
jika kolom tersebut dapat dibatalkan (dan untuk menghindari argumen kolom yang tidak dibutuhkan).Anda dapat melakukan hal berikut:
Sana! Anda baru saja menggunakan nol sebagai nilai default.
Catatan ini akan membantu Anda jika Anda hanya mengakses database dari aplikasi ini. Jika aplikasi lain juga menggunakan database, maka Anda harus melakukan pemeriksaan ini dari database menggunakan atribut anotasi columnDefinition Cameron's , atau cara lain.
sumber
Example
objek sebagai prototipe untuk pencarian. Setelah menetapkan nilai default, kueri contoh Hibernate tidak akan lagi mengabaikan kolom terkait di mana sebelumnya akan mengabaikannya karena itu nol. Pendekatan yang lebih baik adalah mengatur semua nilai default sesaat sebelum menjalankan Hibernatesave()
atauupdate()
. Ini lebih baik meniru perilaku database yang menetapkan nilai default saat menyimpan baris.null
misalnya). Menggunakan@PrePersist
dan@PreUpdate
merupakan pilihan yang lebih baik.columnDefinition
properti tidak independen-database dan@PrePersist
menimpa pengaturan Anda sebelum menyisipkan, "nilai default" adalah sesuatu yang lain, nilai default digunakan ketika nilai tidak diatur secara eksplisit.pendekatan lain menggunakan javax.persistence.PrePersist
sumber
if (createdt != null) createdt = new Date();
atau sesuatu? Saat ini, ini akan menimpa nilai yang ditentukan secara eksplisit, yang membuatnya tidak benar-benar default.if (createdt == null) createdt = new Date();
null
cek.Pada 2017, JPA 2.1 masih memiliki hanya
@Column(columnDefinition='...')
yang Anda menempatkan definisi SQL literal kolom. Yang cukup tidak fleksibel dan memaksa Anda untuk juga mendeklarasikan aspek-aspek lain seperti jenis, hubungan pendek pandangan implementasi JPA tentang masalah itu.Hibernate, punya ini:
Dua catatan untuk itu:
1) Jangan takut menjadi tidak standar. Bekerja sebagai pengembang JBoss, saya telah melihat beberapa proses spesifikasi. Spesifikasi ini pada dasarnya adalah garis dasar bahwa para pemain besar di bidang yang diberikan bersedia berkomitmen untuk mendukung untuk dekade berikutnya. Itu benar untuk keamanan, untuk olahpesan, ORM tidak ada bedanya (walaupun JPA mencakup cukup banyak). Pengalaman saya sebagai pengembang adalah bahwa dalam aplikasi yang kompleks, cepat atau lambat Anda akan memerlukan API yang tidak standar. Dan
@ColumnDefault
merupakan contoh ketika itu melampaui negatif menggunakan solusi non-standar.2) Menyenangkan bagaimana semua orang melambaikan inisialisasi @PrePersist atau anggota konstruktor. Tapi itu TIDAK sama. Bagaimana dengan pembaruan SQL massal? Bagaimana dengan pernyataan yang tidak mengatur kolom?
DEFAULT
memiliki perannya dan itu tidak dapat diganti dengan menginisialisasi anggota kelas Java.sumber
JPA tidak mendukung itu dan akan berguna jika itu terjadi. Menggunakan columnDefinition khusus untuk DB dan tidak dapat diterima dalam banyak kasus. pengaturan default di kelas tidak cukup ketika Anda mengambil catatan yang memiliki nilai nol (yang biasanya terjadi ketika Anda menjalankan kembali tes DBUnit lama). Apa yang saya lakukan adalah ini:
Java auto-boxing sangat membantu dalam hal itu.
sumber
Melihat ketika saya menemukan ini dari Google ketika mencoba untuk memecahkan masalah yang sama, saya hanya akan melempar solusi yang saya buat seandainya seseorang merasa berguna.
Dari sudut pandang saya hanya ada 1 solusi untuk masalah ini - @PrePersist. Jika Anda melakukannya di @PrePersist, Anda harus memeriksa apakah nilainya sudah ditetapkan.
sumber
@PrePersist
usecase OP.@Column(columnDefinition=...)
sepertinya tidak elegan.Saya baru saja menguji masalahnya. Ini bekerja dengan baik. Terima kasih atas petunjuknya.
Tentang komentar:
Yang ini tidak menetapkan nilai kolom default di database (tentu saja).
sumber
Anda dapat menggunakan java reflect api:
Ini biasa:
sumber
Field[] fields = object.getClass().getDeclaredFields();
dalamfor()
mungkin juga oke. Dan juga tambahkanfinal
ke parameter / pengecualian yang ditangkap karena Anda tidak inginobject
dimodifikasi secara tidak sengaja. Juga menambahkan cek padanull
:if (null == object) { throw new NullPointerException("Parameter 'object' is null"); }
. Itu memastikan bahwaobject.getClass()
itu aman untuk memanggil dan tidak memicuNPE
. Alasannya adalah untuk menghindari kesalahan oleh programmer yang malas. ;-)Saya menggunakan
columnDefinition
dan itu bekerja dengan sangat baiksumber
Anda tidak dapat melakukan ini dengan anotasi kolom. Saya pikir satu-satunya cara adalah menetapkan nilai default ketika sebuah objek dibuat. Mungkin konstruktor default akan menjadi tempat yang tepat untuk melakukan itu.
sumber
@Column
sekitar. Dan saya juga kehilangan komentar yang ditetapkan (diambil dari Java doctag).Dalam kasus saya, saya memodifikasi kode sumber hibernate-core, untuk memperkenalkan anotasi baru
@DefaultValue
:Nah, ini adalah solusi hibernate-only.
sumber
@Column(columnDefinition='...')
tidak berfungsi ketika Anda menetapkan batasan default dalam database saat memasukkan data.insertable = false
dan menghapuscolumnDefinition='...'
dari anotasi, maka database akan secara otomatis memasukkan nilai default dari database.insertable = false
Hibernate / JPA, itu akan berfungsi.sumber
Dalam kasus saya karena bidang ini adalah LocalDateTime yang saya gunakan ini, direkomendasikan karena independensi vendor
sumber
Baik anotasi JPA maupun Hibernate tidak mendukung gagasan nilai kolom default. Sebagai solusi untuk batasan ini, setel semua nilai default sesaat sebelum Anda menjalankan Hibernate
save()
atauupdate()
pada sesi. Ini sedekat mungkin (pendek dari Hibernate pengaturan nilai default) meniru perilaku database yang menetapkan nilai default saat menyimpan baris dalam tabel.Tidak seperti pengaturan nilai default di kelas model seperti yang disarankan jawaban alternatif ini , pendekatan ini juga memastikan bahwa kriteria kueri yang menggunakan
Example
objek sebagai prototipe untuk pencarian akan terus bekerja seperti sebelumnya. Ketika Anda menetapkan nilai default atribut nullable (yang memiliki tipe non-primitif) di kelas model, contoh-contoh Hibernate tidak akan lagi mengabaikan kolom terkait di mana sebelumnya akan mengabaikannya karena itu nol.sumber
Ini tidak mungkin di JPA.
Inilah yang dapat Anda lakukan dengan anotasi Kolom: http://java.sun.com/javaee/5/docs/api/javax/persistence/Column.html
sumber
Jika Anda menggunakan ganda, Anda dapat menggunakan yang berikut:
Ya itu spesifik db.
sumber
Anda bisa menentukan nilai default di perancang database, atau saat Anda membuat tabel. Sebagai contoh di SQL Server Anda dapat mengatur kubah default bidang tanggal ke (
getDate()
). Gunakaninsertable=false
seperti yang disebutkan dalam definisi kolom Anda. JPA tidak akan menentukan kolom pada sisipan dan database akan menghasilkan nilai untuk Anda.sumber
Anda perlu
insertable=false
di dalam@Column
anotasi Anda . JPA akan mengabaikan kolom itu saat memasukkan dalam database dan nilai default akan digunakan.Lihat tautan ini: http://mariemjabloun.blogspot.com/2014/03/resolved-set-database-default-value-in.html
sumber
nullable=false
akan gagal denganSqlException
:Caused by: java.sql.SQLException: Column 'opening_times_created' cannot be null
. Di sini saya lupa mengatur cap waktu "dibuat" denganopeningTime.setOpeningCreated(new Date())
. Ini adalah cara yang bagus untuk memiliki konsistensi tetapi itu yang tidak ditanyakan si penanya.