Apakah boleh menjalankan aplikasi Hibernate yang dikonfigurasikan hbm2ddl.auto=update
untuk memperbarui skema basis data di lingkungan produksi?
Apakah boleh menjalankan aplikasi Hibernate yang dikonfigurasikan hbm2ddl.auto=update
untuk memperbarui skema basis data di lingkungan produksi?
Jawaban:
Tidak, ini tidak aman.
Meskipun upaya terbaik dari tim Hibernate, Anda tidak bisa mengandalkan pembaruan otomatis dalam produksi . Tulis tambalan Anda sendiri, ulas dengan DBA, ujilah, lalu terapkan secara manual.
Secara teoritis, jika pembaruan hbm2ddl bekerja dalam pengembangan, itu harus bekerja dalam produksi juga. Namun dalam kenyataannya, tidak selalu demikian.
Bahkan jika itu berhasil OK, itu mungkin kurang optimal. DBA dibayar sebanyak itu karena suatu alasan.
Kami melakukannya dalam produksi meskipun dengan aplikasi yang tidak kritis misi dan tanpa DBA dibayar tinggi pada staf. Ini hanya satu proses manual yang kurang dari kesalahan manusia - aplikasi dapat mendeteksi perbedaan dan melakukan hal yang benar, plus Anda mungkin telah mengujinya di berbagai pengembangan dan lingkungan pengujian.
Satu peringatan - di lingkungan yang berkerumun Anda mungkin ingin menghindarinya karena beberapa aplikasi dapat muncul pada saat yang sama dan mencoba untuk memodifikasi skema yang mungkin buruk. Atau masukkan mekanisme di mana hanya satu instance diizinkan untuk memperbarui skema.
Pembuat yang berhibernasi mencegahnya dalam lingkungan produksi di buku mereka "Java Persistence with Hibernate" :
PERINGATAN: Kami telah melihat pengguna Hibernasi mencoba menggunakan SchemaUpdate untuk memperbarui skema database produksi secara otomatis. Ini dapat dengan cepat berakhir dengan bencana dan tidak akan diizinkan oleh DBA Anda.
Lihat LiquiBase XML untuk menyimpan daftar perubahan pembaruan. Saya belum pernah menggunakannya sampai tahun ini, tetapi saya menemukan bahwa sangat mudah untuk belajar dan membuat kontrol revisi DB / migrasi / manajemen perubahan sangat mudah. Saya bekerja pada proyek Groovy / Grails, dan Grails menggunakan Hibernate di bawahnya untuk semua ORM-nya (disebut "GORM"). Kami menggunakan Liquibase untuk mengelola semua perubahan skema SQL, yang kami lakukan cukup sering karena aplikasi kami berkembang dengan fitur-fitur baru.
Pada dasarnya, Anda menyimpan file perubahan XML yang terus Anda tambahkan saat aplikasi Anda berkembang. File ini disimpan di git (atau apa pun yang Anda gunakan) dengan sisa proyek Anda. Ketika aplikasi Anda digunakan, Liquibase memeriksa tabel changelog di DB yang Anda sambungkan sehingga ia akan tahu apa yang telah diterapkan, lalu aplikasi itu secara cerdas hanya menerapkan perubahan apa pun yang belum diterapkan dari file. Ini berfungsi sangat bagus dalam praktiknya, dan jika Anda menggunakannya untuk semua perubahan skema Anda, maka Anda dapat 100% yakin bahwa kode yang Anda checkout dan gunakan akan selalu dapat terhubung ke skema database yang sepenuhnya kompatibel.
Yang luar biasa adalah bahwa saya dapat mengambil database mysql yang benar-benar kosong di laptop saya, menjalankan aplikasi, dan segera skema diatur untuk saya. Ini juga membuatnya mudah untuk menguji perubahan skema dengan menerapkannya pada dev-lokal atau pementasan db terlebih dahulu.
Cara termudah untuk memulai mungkin dengan mengambil DB yang ada dan kemudian menggunakan Liquibase untuk menghasilkan file baseline.xml awal. Kemudian di masa depan Anda bisa menambahkannya dan membiarkan liquibase mengambil alih mengelola perubahan skema.
hbm2ddl.auto=update
sehingga pemetaan Kelas / DB Anda divalidasi dan Anda memiliki kendali penuh atas pembuatan DB melalui liquibase. Bagaimana menurut anda?
validate
Saya akan memilih tidak. Hibernate tampaknya tidak mengerti kapan tipe data untuk kolom telah berubah. Contoh (menggunakan MySQL):
String with @Column(length=50) ==> varchar(50)
changed to
String with @Column(length=100) ==> still varchar(50), not changed to varchar(100)
@Temporal(TemporalType.TIMESTAMP,TIME,DATE) will not update the DB columns if changed
Mungkin ada contoh lain juga, seperti mendorong panjang kolom String lebih dari 255 dan melihatnya dikonversi ke teks, teks menengah, dll.
Memang, saya tidak berpikir ada cara untuk "mengkonversi tipe data" dengan tanpa membuat kolom baru, menyalin data dan membuang kolom lama. Tetapi begitu database Anda memiliki kolom yang tidak mencerminkan pemetaan Hibernate saat ini, Anda hidup dengan sangat berbahaya ...
Flyway adalah opsi yang baik untuk mengatasi masalah ini:
@Column(length = 45)
menjadi @Column(length = 255)
. Dapat memverifikasi bahwa Hibernate 4.3.6.Final benar memperbarui skema database menggunakan hbm2ddl.auto=update
. (Satu hal yang perlu disebutkan adalah database saat ini tidak memiliki data di dalamnya - hanya strukturnya.)
Hibernate harus meletakkan penafian tentang tidak menggunakan pembaruan otomatis di prod untuk melindungi diri mereka sendiri ketika orang-orang yang tidak tahu apa yang mereka lakukan menggunakannya dalam situasi di mana seharusnya tidak digunakan.
Memang situasi di mana itu tidak boleh digunakan sangat melebihi jumlah yang OK.
Saya telah menggunakannya selama bertahun-tahun di banyak proyek yang berbeda dan tidak pernah memiliki satu masalah pun. Itu bukan jawaban yang lemah, dan itu bukan pengkodean koboi. Itu fakta sejarah.
Seseorang yang mengatakan "tidak pernah melakukannya dalam produksi" sedang memikirkan serangkaian penyebaran produksi yang spesifik, yaitu yang ia kenal (perusahaannya, industrinya, dll).
Alam semesta "penyebaran produksi" sangat luas dan beragam.
Pengembang Hibernate yang berpengalaman tahu persis apa yang akan dihasilkan oleh DDL dari konfigurasi pemetaan yang diberikan. Selama Anda menguji dan memvalidasi bahwa apa yang Anda harapkan berakhir di DDL (dalam dev, qa, pementasan, dll), Anda baik-baik saja.
Saat Anda menambahkan banyak fitur, pembaruan skema otomatis dapat menghemat waktu nyata.
Daftar pembaruan otomatis hal-hal yang tidak akan ditangani tidak ada habisnya, tetapi beberapa contohnya adalah migrasi data, menambahkan kolom yang tidak dapat dibatalkan, perubahan nama kolom, dll, dll.
Anda juga perlu berhati-hati di lingkungan yang berkerumun.
Tetapi sekali lagi, jika Anda tahu semua hal ini, Anda tidak akan menanyakan pertanyaan ini. Hmm. . . OK, jika Anda mengajukan pertanyaan ini, Anda harus menunggu sampai Anda memiliki banyak pengalaman dengan pembaruan Hibernate dan skema otomatis sebelum Anda berpikir untuk menggunakannya di prod.
Seperti yang saya jelaskan di artikel ini , itu bukan ide yang baik untuk digunakan hbm2ddl.auto
dalam produksi.
Satu-satunya cara untuk mengelola skema basis data adalah dengan menggunakan skrip migrasi tambahan karena:
Bahkan Panduan Pengguna Hibernate menyarankan Anda untuk tidak menggunakan hbm2ddl
alat untuk lingkungan produksi.
SchemaExport
seperti yang ditunjukkan oleh test case ini .
Kami melakukannya dalam proyek yang berjalan dalam produksi selama berbulan-bulan sekarang dan tidak pernah memiliki masalah sejauh ini. Ingatlah 2 bahan yang dibutuhkan untuk resep ini:
Desain model objek Anda dengan pendekatan kompatibilitas ke belakang, yaitu objek dan atribut yang sudah ketinggalan zaman alih-alih menghapus / mengubahnya. Ini berarti bahwa jika Anda perlu mengubah nama objek atau atribut, biarkan yang lama apa adanya, tambahkan yang baru dan tulis semacam skrip migrasi. Jika Anda perlu mengubah hubungan antara objek, jika Anda sudah dalam produksi, ini berarti bahwa desain Anda salah sejak awal, jadi coba pikirkan cara baru untuk mengekspresikan hubungan baru, tanpa memengaruhi data lama.
Selalu cadangkan basis data sebelum penempatan.
Perasaan saya adalah - setelah membaca posting ini - bahwa 90% orang yang mengambil bagian dalam diskusi ini ngeri hanya dengan pemikiran untuk menggunakan otomatisasi seperti ini dalam lingkungan produksi. Beberapa melemparkan bola ke DBA. Luangkan waktu sejenak untuk mempertimbangkan bahwa tidak semua lingkungan produksi akan memberikan DBA dan tidak banyak tim pengembang mampu membelinya (setidaknya untuk proyek-proyek berukuran sedang). Jadi, jika kita berbicara tentang tim di mana setiap orang harus melakukan segalanya, bola ada pada mereka.
Dalam hal ini, mengapa tidak mencoba untuk mendapatkan yang terbaik dari kedua dunia? Alat-alat seperti ini ada di sini untuk membantu, yang - dengan desain dan rencana yang cermat - dapat membantu dalam banyak situasi. Dan percayalah, administrator mungkin awalnya sulit diyakinkan tetapi jika mereka tahu bahwa bola tidak ada di tangan mereka, mereka akan menyukainya.
Secara pribadi, saya tidak akan pernah kembali menulis skrip dengan tangan untuk memperluas segala jenis skema, tapi itu hanya pendapat saya. Dan setelah mulai mengadopsi database tanpa skema NoSQL baru-baru ini, saya dapat melihat bahwa lebih dari segera, semua operasi berbasis skema ini akan menjadi milik masa lalu, jadi Anda sebaiknya mulai mengubah perspektif Anda dan melihat ke depan.
Saya tidak akan mengambil risiko karena Anda mungkin akan kehilangan data yang seharusnya disimpan. hbm2ddl.auto = pembaruan adalah murni cara mudah untuk memperbarui basis data dev Anda.
Dalam kasus saya (Hibernate 3.5.2, Postgresql, Ubuntu), pengaturan hibernate.hbm2ddl.auto=update
hanya membuat tabel baru dan membuat kolom baru di tabel yang sudah ada.
Itu tidak menjatuhkan tabel, atau menjatuhkan kolom, atau mengubah kolom. Ini bisa disebut opsi yang aman, tetapi sesuatu seperti hibernate.hbm2ddl.auto=create_tables add_columns
akan lebih jelas.
Itu tidak aman, tidak disarankan, tetapi itu mungkin.
Saya memiliki pengalaman dalam aplikasi menggunakan opsi pembaruan otomatis dalam produksi.
Masalah utama dan risiko yang ditemukan dalam solusi ini adalah:
Jadi, saya tidak akan merekomendasikan untuk menggunakan pembaruan otomatis dalam produksi.
Jika Anda benar-benar ingin menggunakan pembaruan otomatis dalam produksi, saya sarankan:
Dan, berbeda dari posting lain, saya tidak berpikir pembaruan otomatis diaktifkan itu terkait dengan DBA "dibayar sangat baik" (seperti yang disebutkan dalam posting lain). DBA memiliki hal-hal yang lebih penting untuk dilakukan daripada menulis pernyataan SQL untuk membuat / mengubah / menghapus tabel dan kolom. Tugas sehari-hari sederhana ini dapat dilakukan dan diotomatisasi oleh pengembang dan hanya diberikan kepada tim DBA untuk ditinjau, tidak perlu Hibernate dan DBA "dibayar sangat baik" untuk menulisnya.
Biasanya aplikasi perusahaan di organisasi besar dijalankan dengan hak istimewa yang dikurangi.
Nama pengguna basis data mungkin tidak memiliki DDL
hak istimewa untuk menambahkan kolom yang hbm2ddl.auto=update
membutuhkan.
Saya setuju dengan Vladimir. Administrator di perusahaan saya pasti tidak akan menghargainya jika saya menyarankan kursus semacam itu.
Lebih lanjut, membuat skrip SQL sebagai ganti Hibernate yang mempercayai secara membabi buta memberi Anda kesempatan untuk menghapus bidang yang tidak lagi digunakan. Hibernate tidak melakukan itu.
Dan saya menemukan membandingkan skema produksi dengan skema baru memberi Anda wawasan yang lebih baik untuk apa Anda berubah dalam model data. Anda tahu, tentu saja, karena Anda berhasil, tetapi sekarang Anda melihat semua perubahan dalam sekali jalan. Bahkan yang membuatmu seperti "Apa-apaan ini ?!"
Ada alat yang dapat membuat skema delta untuk Anda, jadi itu bahkan bukan kerja keras. Dan kemudian Anda tahu persis apa yang akan terjadi.
Skema aplikasi dapat berkembang dalam waktu; jika Anda memiliki beberapa instalasi, yang mungkin pada versi yang berbeda, Anda harus memiliki beberapa cara untuk memastikan bahwa aplikasi Anda, semacam alat atau skrip mampu memigrasikan skema dan data dari satu versi secara bertahap ke versi berikutnya.
Memiliki semua kegigihan Anda dalam pemetaan Hibernate (atau anotasi) adalah cara yang sangat baik untuk menjaga evolusi skema terkendali.
Anda harus mempertimbangkan bahwa evolusi skema memiliki beberapa aspek untuk dipertimbangkan:
evolusi skema basis data dalam menambahkan lebih banyak kolom dan tabel
menjatuhkan kolom, tabel, dan relasi lama
mengisi kolom baru dengan default
Alat Hibernate penting khususnya dalam kasus (seperti dalam pengalaman saya) Anda memiliki versi yang berbeda dari aplikasi yang sama pada berbagai jenis database.
Poin 3 sangat sensitif jika Anda menggunakan Hibernate, seperti jika Anda memperkenalkan properti bernilai boolean baru atau numerik, jika Hibernate akan menemukan nilai nol di kolom tersebut, jika akan memunculkan pengecualian.
Jadi apa yang akan saya lakukan adalah: lakukan memang menggunakan alat Hibernate kapasitas pembaruan skema, tetapi Anda harus menambahkan di sampingnya beberapa data dan panggilan balik pemeliharaan skema, seperti untuk mengisi default, menjatuhkan kolom tidak lagi digunakan, dan sejenisnya. Dengan cara ini Anda mendapatkan keuntungan (skrip pembaruan skema basis data independen dan menghindari pengkodean duplikat dari pembaruan, dalam ketekunan dan dalam skrip) tetapi Anda juga mencakup semua aspek operasi.
Jadi misalnya jika pembaruan versi hanya terdiri dari menambahkan properti bernilai varchar (maka kolom), yang mungkin default ke nol, dengan pembaruan otomatis Anda akan selesai. Di mana lebih banyak kompleksitas diperlukan, lebih banyak pekerjaan akan diperlukan.
Ini mengasumsikan bahwa aplikasi ketika diperbarui mampu memperbarui skema (dapat dilakukan), yang juga berarti harus memiliki hak pengguna untuk melakukannya pada skema. Jika kebijakan pelanggan mencegah hal ini (kemungkinan kasus Kadal Otak), Anda harus menyediakan skrip khusus basis data.