Bagaimana tepatnya properti spring.jpa.hibernate.ddl-auto bekerja di Spring?

127

Saya sedang mengerjakan proyek aplikasi boot Spring saya dan memperhatikan bahwa, terkadang ada kesalahan waktu koneksi habis ke Database saya di server lain (SQL Server). Ini terjadi secara khusus ketika saya mencoba melakukan migrasi skrip dengan FlyWaytetapi berfungsi setelah beberapa kali mencoba.

Kemudian saya perhatikan bahwa saya tidak menentukan spring.jpa.hibernate.ddl-autodalam file properti saya. Saya melakukan beberapa penelitian dan menemukan bahwa itu disarankan untuk ditambahkan spring.jpa.hibernate.ddl-auto= create-dropdalam pengembangan. Dan mengubahnya menjadi: spring.jpa.hibernate.ddl-auto= nonedalam produksi.

Tapi saya tidak benar-benar mengerti bagaimana cara kerjanya dan bagaimana hibernate menghasilkan skema database menggunakan create-dropatau nonenilai. Bisakah Anda menjelaskan secara teknis bagaimana cara kerjanya, dan apa saja rekomendasi untuk menggunakan properti ini dalam pengembangan dan pada server produksi. Terima kasih

METTAIBI
sumber
1
FWIW JPA 2.1 memiliki properti standar javax.persistence.schema-generation.database.action jadi tidak benar-benar melihat kebutuhan untuk menggunakan properti khusus vendor JPA untuk pembuatan skema.
Neil Stockton
@NeilStockton Satu ide yang kami jelajahi dengan Hibernate 6 adalah kemampuan untuk dapat mengontrol pembuatan skema secara berbeda berdasarkan kategori; misalnya tabel orm Anda mungkin nonetetapi Anda mungkin ingin tabel Hibernate Search dan Envers dibuat menggunakan updatekarena mereka dikelola secara internal oleh proyek-proyek tersebut dan Anda tidak ingin mengelolanya sendiri secara manual. Sekarang kami mengontrol ini secara global untuk semua tabel terlepas dari asal / sumbernya. Ini selanjutnya akan menjadi alasan untuk menggunakan opsi khusus vendor jika Anda ingin menggunakan ini.
Naros

Jawaban:

213

Sebagai catatan, spring.jpa.hibernate.ddl-autoproperti ini khusus untuk Spring Data JPA dan merupakan cara mereka untuk menentukan nilai yang pada akhirnya akan diteruskan ke Hibernate di bawah properti yang diketahuinya , hibernate.hbm2ddl.auto.

Nilai-nilai create, create-drop, validate, dan updatepada dasarnya mempengaruhi bagaimana pengelolaan alat skema akan memanipulasi skema database saat startup.

Misalnya, updateoperasi akan meminta API driver JDBC untuk mendapatkan metadata database dan kemudian Hibernate membandingkan model objek yang dibuatnya berdasarkan pembacaan kelas beranotasi atau pemetaan XML HBM Anda dan akan mencoba menyesuaikan skema dengan cepat.

The updateoperasi misalnya akan mencoba untuk menambahkan kolom baru, kendala, dll tapi tidak akan pernah menghapus kolom atau kendala yang mungkin telah ada sebelumnya tetapi tidak lagi melakukan sebagai bagian dari model objek dari run sebelumnya.

Biasanya dalam skenario kasus pengujian, Anda kemungkinan akan menggunakan create-dropsehingga Anda membuat skema, kasus pengujian Anda menambahkan beberapa data tiruan, Anda menjalankan pengujian, dan kemudian selama pembersihan kasus pengujian, objek skema dihapus, meninggalkan database kosong.

Dalam pengembangan, sering kali terlihat developer menggunakan updateuntuk mengubah skema secara otomatis untuk menambahkan tambahan baru saat memulai ulang. Tapi sekali lagi mengerti, ini tidak menghapus kolom atau batasan yang mungkin ada dari eksekusi sebelumnya yang tidak lagi diperlukan.

Dalam produksi, sering kali Anda sangat disarankan untuk menggunakan noneatau tidak menentukan properti ini. Itu karena praktik umum bagi DBA untuk meninjau skrip migrasi untuk perubahan database, terutama jika database Anda dibagikan ke beberapa layanan dan aplikasi.

Naros
sumber
11
Ya, jangan pernah menggunakan generasi ddl dalam produksi. Kami membuat skrip awal untuk struktur tabel menggunakan ddl, dan melibatkan DBA dalam prosesnya. Kami kemudian menyertakan skrip db sebagai bagian dari unit penerapan, dan menjalankannya menggunakan Flyway saat aplikasi diterapkan. Ketika kita perlu memodifikasi database, kita menambahkan skrip baru ke versi aplikasi berikutnya dan menerapkannya ke staging. Flyway secara otomatis akan mendeteksi versi saat ini dan menjalankan skrip yang diperlukan untuk membawa database ke versi terbaru. Jika semuanya berhasil, kami menerapkannya ke produksi.
Klaus Groenbaek
1
bagaimana jika kita tidak menentukan properti ini? misalnya saya memiliki <bean id = "sessionFactory" class = "org.springframework.orm.hibernate5.LocalSessionFactoryBean"> ... <prop key = "hibernate.hbm2ddl.auto"> update </prop> saya sendiri dan untuk beberapa alasan tabel saya selalu dijatuhkan, sampai saya menambahkan properti yang disebutkan di atas ;; ps: maaf untuk contoh kode)
Ţîgan Ion
11
Mengapa tidak validatedi Production Env?
Shamal Karunarathne
20
@ShamalKarunarathne Aplikasi dapat digunakan validatedalam produksi, tetapi biasanya itu harus menjadi pengaturan yang Anda gunakan dalam kualitas / lingkungan pengujian untuk memverifikasi bahwa skrip database yang telah Anda tulis atau terapkan ke alat migrasi database Anda akurat. Alasan lain untuk tidak menggunakan validatedalam produksi adalah karena hal ini bisa menjadi hambatan selama proses startup aplikasi Anda, terutama jika model objek Anda berukuran cukup luas atau jika faktor terkait jaringan lainnya ikut bermain.
Naros
1
Tanpa jejak tumpukan yang tepat sulit untuk berspekulasi; Namun, tebakan pertama saya orderadalah bahwa hal itu ditafsirkan secara tidak benar oleh parser SQL karena itu adalah kata kunci jika tidak di-escape.
Naros