Apa nilai yang mungkin dari konfigurasi Hibernate hbm2ddl.auto dan apa yang mereka lakukan

1085

Saya benar-benar ingin tahu lebih banyak tentang pembaruan, ekspor, dan nilai-nilai yang dapat diberikan hibernate.hbm2ddl.auto
saya, saya perlu tahu kapan harus menggunakan pembaruan dan kapan tidak? Dan apa alternatifnya?

Ini adalah perubahan yang bisa terjadi pada DB:

  • tabel baru
  • kolom baru di tabel lama
  • kolom dihapus
  • tipe data kolom berubah
  • tipe kolom mengubah atributnya
  • tabel terjatuh
  • nilai kolom berubah

Dalam setiap kasus, apa solusi terbaik?

Vlad Mihalcea
sumber

Jawaban:

1083

Dari dokumentasi komunitas :

hibernate.hbm2ddl.auto Secara otomatis memvalidasi atau mengekspor skema DDL ke database ketika SessionFactory dibuat. Dengan create-drop, skema basis data akan dihapus ketika SessionFactory ditutup secara eksplisit.

misalnya validasi | perbarui | buat | buat-jatuhkan

Jadi daftar opsi yang mungkin adalah,

  • memvalidasi : memvalidasi skema, tidak membuat perubahan pada database.
  • perbarui : perbarui skema.
  • create : create the schema, menghancurkan data sebelumnya.
  • create-drop : jatuhkan skema ketika SessionFactory ditutup secara eksplisit, biasanya ketika aplikasi dihentikan.
  • tidak ada : tidak melakukan apa pun dengan skema, tidak membuat perubahan pada database

Opsi ini tampaknya dimaksudkan sebagai alat pengembang dan bukan untuk memfasilitasi basis data tingkat produksi, Anda mungkin ingin melihat pada pertanyaan berikut; Hibernate: hbm2ddl.auto = pembaruan dalam produksi?

James McMahon
sumber
14
Cukup baca dokumen hibernasi ... untuk nilai yang valid, dikatakan: "misalnya" ... apakah ada nilai valid lainnya?
Ta Sas
16
Saya pikir itu mengatakan "misalnya" karena itu hanya dokumentasi komunitas, jika seseorang tertarik pada semua nilai yang mungkin, itu dapat ditemukan di javadoc Hibernate. (Dan ya, hanya empat opsi yang ada) docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/cfg/…
szegedi
4
memvalidasi mengatakan memvalidasi skema, apa sebenarnya artinya ??
Hussain Akhtar Wahid 'Ghouri'
6
Anda juga dapat menggunakan 'aardvark', atau 'merpati' atau kata lain, jika Anda ingin hibernate tidak melakukan apa-apa. Bukannya saya akan merekomendasikan itu tentu saja!
Ward
2
Tambahan kecil untuk opsi buat-jatuhkan. Jika opsi ini digunakan, ia tidak menjatuhkan seluruh skema melainkan menjatuhkan tabel yang pemetaannya tersedia saat menjalankan ini. Misalnya jika database dengan Skema S memiliki tabel A, B, C dan kode java memiliki pemetaan untuk A dan B saja maka Hibernate tidak akan menjatuhkan tabel C.
Aditya
194

Ada juga nilai tidak berdokumen "tidak ada" untuk menonaktifkannya sepenuhnya.

Michiel Verkaik
sumber
7
Ini sebenarnya cukup berguna karena validasi skema Hibernate terkadang gagal untuk skema yang benar-benar valid.
Michael Piefel
Saya baru saja akan meminta sesuatu seperti ini. Tujuan saya adalah mengurangi waktu startup.
digao_mb
46
'string kosong' lebih baik daripada 'tidak ada' . Untuk menggunakan 'tidak ada', Anda akan menerima pesan peringatan: org.hibernate.cfg.SettingsFactory - Nilai yang tidak dikenal untuk "hibernate.hbm2ddl.auto": none
okwap
14
Saya sudah menambalnya. Menambahkan "tidak ada" sebagai konstanta yang valid secara eksplisit.
Sanne
9
Saya suka "hibernate.hbm2ddl.auto = kentang" di atas yang lain stackoverflow.com/a/15810379/838444
Sneg
161

Properti konfigurasi disebut hibernate.hbm2ddl.auto

Dalam lingkungan pengembangan kami, kami menetapkan hibernate.hbm2ddl.auto=create-dropuntuk menjatuhkan dan membuat basis data yang bersih setiap kali kami menggunakan, sehingga basis data kami berada dalam kondisi yang diketahui.

Secara teori, Anda dapat mengatur hibernate.hbm2ddl.auto=updateuntuk memperbarui basis data Anda dengan perubahan pada model Anda, tetapi saya tidak akan mempercayainya pada basis data produksi. Versi dokumentasi yang lebih lama mengatakan bahwa ini adalah percobaan, setidaknya; Saya tidak tahu status saat ini.

Karena itu, untuk basis data produksi kami, jangan setel hibernate.hbm2ddl.auto- defaultnya adalah tidak membuat perubahan basis data. Sebagai gantinya, kami secara manual membuat skrip pembaruan SQL DDL yang menerapkan perubahan dari satu versi ke yang berikutnya.

Peter Hilton
sumber
5
Sebenarnya, per dokumentasi, create-drop membuat tabel database dan menjatuhkannya ketika sesi pabrik ditutup secara eksplisit. Itu tidak menjatuhkan tabel ketika sesi pabrik dibuat.
Frans
4
Tidak, keduanya buat-jatuhkan dan buat jatuhkan tabel saat sesi pabrik dibuat, lalu buat-jatuhkan tabel juga saat sesi pabrik ditutup. Lihat stackoverflow.com/a/6752698/1536382
Testo Testini
apakah membuat hibernate.hbm2ddl.auto = membuat-drop dalam produksi dapat menyebabkan beberapa waktu koneksi habis dalam produksi?
METTAIBI
51

Saya akan menggunakan liquibase untuk memperbarui db Anda. fitur pembaruan skema hibernate benar-benar hanya baik untuk pengembang ketika mereka sedang mengembangkan fitur baru. Dalam situasi produksi, peningkatan db perlu ditangani dengan lebih hati-hati.

Menepuk
sumber
6
Lihat stackoverflow.com/questions/221379/… untuk alasan Anda tidak boleh menggunakan hbm2ddl untuk produksi.
Nathan Voxland
51

Meskipun itu posting yang cukup lama tetapi ketika saya melakukan riset tentang topik itu jadi berpikir untuk membagikannya.

hibernate.hbm2ddl.auto

Sesuai dokumentasi itu dapat memiliki empat nilai yang valid:

buat | perbarui | validasi | buat-jatuhkan

Berikut ini adalah penjelasan perilaku yang ditunjukkan oleh nilai ini:

  • buat : - buat skema, data yang sebelumnya ada (jika ada) dalam skema hilang
  • perbarui: - perbarui skema dengan nilai yang diberikan.
  • validasi: - memvalidasi skema. Itu tidak membuat perubahan dalam DB.
  • create-drop: - buat skema dengan menghancurkan data yang ada sebelumnya (jika ada). Itu juga menjatuhkan skema database ketika SessionFactory ditutup.

Berikut ini adalah poin penting yang perlu diperhatikan:

  • Dalam hal pembaruan , jika skema tidak ada dalam DB maka skema dibuat.
  • Dalam kasus validasi , jika skema tidak ada dalam DB, itu tidak dibuat. Sebaliknya, itu akan menimbulkan kesalahan: -Table not found:<table name>
  • Dalam kasus buat-jatuhkan , skema tidak dibatalkan saat menutup sesi. Itu hanya jatuh pada penutupan SessionFactory.
  • Dalam kasus jika saya memberikan nilai apa pun untuk properti ini (katakanlah abc, alih-alih empat nilai yang dibahas di atas) atau dibiarkan kosong. Ini menunjukkan perilaku berikut:

    -Jika skema tidak ada dalam DB: - Ini menciptakan skema

    -Jika ada skema dalam DB: - perbarui skema.

ya
sumber
Ini memang poin yang sangat penting bahwa skema akan dibuat jika tidak ada, ketika "pembaruan" digunakan.
yuranos
buat-jatuhkan bertentangan ketika membandingkan pernyataan "Penjelasan perilaku" dan "Poin Penting".
VNT
2
Apa perbedaan antara pembaruan dan kosong ?
yashjain12yj
46

Pertama, nilai yang mungkin untuk hbm2ddlproperti konfigurasi adalah yang berikut:

  • none- Tidak ada tindakan yang dilakukan. Skema tidak akan dihasilkan.
  • create-only - Skema basis data akan dibuat.
  • drop - Skema basis data akan dihapus dan dibuat setelahnya.
  • create - Skema basis data akan dihapus dan dibuat setelahnya.
  • create-drop- Skema basis data akan dihapus dan dibuat setelahnya. Setelah menutup SessionFactory, skema basis data akan dihapus.
  • validate - Skema basis data akan divalidasi menggunakan pemetaan entitas.
  • update - Skema basis data akan diperbarui dengan membandingkan skema basis data yang ada dengan pemetaan entitas.

Saya mendedikasikan posting blog untuk strategi generasi Hibernate DDL yang paling umum :

  1. Ini hibernate.hbm2ddl.auto="update"nyaman tetapi kurang fleksibel jika Anda berencana untuk menambahkan fungsi atau menjalankan beberapa skrip khusus.
  2. Pendekatan yang paling fleksibel adalah menggunakan Flyway .

Namun, bahkan jika Anda menggunakan Flyway, Anda masih dapat membuat skrip migrasi awal menggunakan hbm2ddl. Di artikel ini , Anda bisa melihat bagaimana Anda bisa menggabungkan Model Entitas JPA dengan Model Tabel jOOQ.

Vlad Mihalcea
sumber
27

hibernate.hbm2ddl.auto secara otomatis memvalidasi dan mengekspor DDL ke skema ketika sessionFactory dibuat.

Secara default, ia tidak melakukan kreasi atau modifikasi apa pun secara otomatis pada DB. Jika pengguna menetapkan salah satu dari nilai di bawah ini maka ia melakukan perubahan skema DDL secara otomatis.

  • buat - buat membuat skema

    <entry key="hibernate.hbm2ddl.auto" value="create">
  • perbarui - memperbarui skema yang ada

    <entry key="hibernate.hbm2ddl.auto" value="update">
  • memvalidasi - memvalidasi skema yang ada

    <entry key="hibernate.hbm2ddl.auto" value="validate">
  • create-drop - buat dan jatuhkan skema secara otomatis saat sesi dimulai dan berakhir

    <entry key="hibernate.hbm2ddl.auto" value="create-drop">
Vinod Kumawat
sumber
2
bagaimana dengan <entry key = "hibernate.hbm2ddl.auto" value = "none">?
VNT
17

Jika Anda tidak ingin menggunakan Strings di aplikasi Anda dan mencari konstanta yang telah ditentukan, lihatlah org.hibernate.cfg.AvailableSettingskelas yang termasuk dalam Hibernate JAR, di mana Anda akan menemukan konstanta untuk semua pengaturan yang mungkin. Dalam kasus Anda misalnya:

/**
 * Auto export/update schema using hbm2ddl tool. Valid values are <tt>update</tt>,
 * <tt>create</tt>, <tt>create-drop</tt> and <tt>validate</tt>.
 */
String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
Stefan Haberl
sumber
5
Mengapa referensi ke 700+ baris file sumber panjang di atas jawaban langsung dengan hampir 500 vole up?
Pavel Niedoba
... pertanyaan itu tidak masuk akal. Mengapa ada banyak hal? Kenapa aku ada di sini?
spesialisasi
8
  • validate: memvalidasi skema, tidak ada perubahan yang terjadi pada database.
  • update: memperbarui skema dengan permintaan eksekusi saat ini.
  • create: membuat skema baru setiap saat, dan menghancurkan data sebelumnya.
  • create-drop: menjatuhkan skema ketika aplikasi dihentikan atau SessionFactory ditutup secara eksplisit.
thakur vishal
sumber
Apa referensi dokumentasi 'resmi'? - hanya ingin tahu ...
Dirk Schumacher
7

Saya pikir Anda harus berkonsentrasi pada

SchemaExport Class 

Kelas ini Membuat Konfigurasi Anda Dinamis Sehingga memungkinkan Anda untuk memilih suite apa pun yang Anda ...

Checkout [SchemaExport]

Vishal Sharma
sumber
4

validate: Ini memvalidasi skema dan tidak membuat perubahan pada DB.
Asumsikan Anda telah menambahkan kolom baru dalam file pemetaan dan melakukan operasi penyisipan, itu akan memunculkan Pengecualian "melewatkan kolom XYZ" karena skema yang ada berbeda dari objek yang akan Anda masukkan. Jika Anda mengubah tabel dengan menambahkan kolom baru secara manual kemudian melakukan operasi Sisipkan maka pasti akan memasukkan semua kolom bersama dengan kolom baru ke Tabel. Berarti itu tidak membuat perubahan / mengubah skema / tabel yang ada.

update: itu mengubah tabel yang ada di database ketika Anda melakukan operasi. Anda dapat menambah atau menghapus kolom dengan opsi hbm2ddl ini. Tetapi jika Anda akan menambahkan kolom baru yang 'TIDAK NULL' maka itu akan mengabaikan menambahkan kolom tertentu ke DB. Karena Tabel harus kosong jika Anda ingin menambahkan kolom 'TIDAK NULL' ke tabel yang ada.

Arun Raaj
sumber
3

Sejak 5.0 , Anda sekarang dapat menemukan nilai-nilai itu di khusus Enum: org.hibernate.boot.SchemaAutoTooling(ditingkatkan dengan nilaiNONE sejak 5.2).

Atau bahkan lebih baik, karena 5.1 , Anda juga dapat menggunakanorg.hibernate.tool.schema.Action Enum yang menggabungkan aksi-aksi Hibernate JPA 2 dan "legacy" DDL.

Namun , Anda belum dapat mengkonfigurasi DataSourceprogram dengan ini. Akan lebih baik untuk menggunakan ini dikombinasikan dengan org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTOtetapi kode saat ini mengharapkan Stringnilai (kutipan diambil dari SessionFactoryBuilderImpl):

this.schemaAutoTooling = SchemaAutoTooling.interpret( (String) configurationSettings.get( AvailableSettings.HBM2DDL_AUTO ) );

... dan enumnilai internal keduanya org.hibernate.boot.SchemaAutoToolingdan org.hibernate.tool.schema.Actiontidak diekspos secara publik.

Di bawah ini, contoh DataSourcekonfigurasi program (digunakan pada salah satu aplikasi Boot Musim Semi saya) yang menggunakan terima kasih gambit .name().toLowerCase()tetapi hanya berfungsi dengan nilai tanpa tanda hubung (tidak create-dropmisalnya):

@Bean(name = ENTITY_MANAGER_NAME)
public LocalContainerEntityManagerFactoryBean internalEntityManagerFactory(
        EntityManagerFactoryBuilder builder,
        @Qualifier(DATA_SOURCE_NAME) DataSource internalDataSource) {

    Map<String, Object> properties = new HashMap<>();
    properties.put(AvailableSettings.HBM2DDL_AUTO, SchemaAutoTooling.CREATE.name().toLowerCase());
    properties.put(AvailableSettings.DIALECT, H2Dialect.class.getName());

    return builder
            .dataSource(internalDataSource)
            .packages(JpaModelsScanEntry.class, Jsr310JpaConverters.class)
            .persistenceUnit(PERSISTENCE_UNIT_NAME)
            .properties(properties)
            .build();
}
Doc Davluz
sumber
0

Kepada siapa mencari nilai default ...

Itu ditulis dalam kode sumber di versi 2.0.5 dari boot-spring dan 1.1.0 di JpaProperties:

    /**
     * DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto"
     * property. Defaults to "create-drop" when using an embedded database and no
     * schema manager was detected. Otherwise, defaults to "none".
     */
    private String ddlAuto;
ibrahim demir
sumber