hibernate.hbm2ddl.auto
更新、エクスポート、および更新をいつ使用し、いつ使用しないかを知る必要があるに与えることができる値について、本当に知りたいですか? そして、代替手段は何ですか?
これらは、DB で発生する可能性のある変更です。
- 新しいテーブル
- 古いテーブルの新しい列
- 列が削除されました
- 列のデータ型が変更されました
- 列のタイプがその属性を変更しました
- 削除されたテーブル
- 列の値が変更されました
それぞれの場合、最善の解決策は何ですか?
完全に無効にする「none」という文書化されていない値もあります。
構成プロパティが呼び出されますhibernate.hbm2ddl.auto
私たちの開発環境ではhibernate.hbm2ddl.auto=create-drop
、データベースが既知の状態になるように、展開するたびにクリーンなデータベースをドロップして作成するように設定しました。
理論的にはhibernate.hbm2ddl.auto=update
、モデルに変更を加えてデータベースを更新するように設定できますが、本番データベースでは信頼できません。ドキュメントの以前のバージョンでは、これは少なくとも実験的なものであると述べられていました。現在の状況はわかりません。
したがって、本番データベースでは設定しないでくださいhibernate.hbm2ddl.auto
。デフォルトでは、データベースは変更されません。代わりに、あるバージョンから次のバージョンに変更を適用する SQL DDL 更新スクリプトを手動で作成します。
データベースの更新にはliquibaseを使用します。hibernate のスキーマ更新機能は、開発者が新しい機能を開発している間だけ、実際に問題ありません。本番環境では、db のアップグレードをより慎重に処理する必要があります。
かなり古い投稿ですが、このトピックについて調査したので、共有することを考えました。
hibernate.hbm2ddl.auto
ドキュメントによると、次の 4 つの有効な値を持つことができます。
作成 | アップデート | 検証 | 作成ドロップ
以下は、これらの値によって示される動作の説明です。
注目すべき重要な点は次のとおりです。
Table not found:<table name>
このプロパティに値を指定した場合 (上記の 4 つの値の代わりに abc など)、または空白のままにします。次の動作を示します。
-スキーマがDBに存在しない場合:- スキーマを作成します
-DB にスキーマが存在する場合:-スキーマを更新します。
アプリで文字列を使用したくない場合、事前定義された定数を探しているorg.hibernate.cfg.AvailableSettings
場合は、Hibernate JAR に含まれるクラスを参照してください。ここには、可能なすべての設定の定数があります。たとえば、あなたの場合:
/**
* 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";
validate
: スキーマを検証し、DB に変更を加えません。
マッピング ファイルに新しい列を追加して挿入操作を実行すると、既存のスキーマが挿入しようとしているオブジェクトと異なるため、「XYZ 列がありません」という例外がスローされます。その新しい列を手動で追加してテーブルを変更し、挿入操作を実行すると、新しい列とともにすべての列がテーブルに確実に挿入されます。既存のスキーマ/テーブルを変更/変更しないことを意味します。
update
: 操作を実行すると、データベース内の既存のテーブルが変更されます。hbm2ddl のこのオプションを使用して、列を追加または削除できます。ただし、「NOT NULL」である新しい列を追加しようとすると、その特定の列を DB に追加することは無視されます。既存のテーブルに「NOT NULL」列を追加する場合、テーブルは空でなければならないためです。
5.0 以降Enum
、専用の:でこれらの値を見つけることができるようになりました( 5.2 以降org.hibernate.boot.SchemaAutoTooling
、 value で強化されています)。NONE
さらに良いことに、5.1 以降では、JPA 2 と「レガシー」Hibernate DDL アクションを組み合わせた を使用することもできます。org.hibernate.tool.schema.Action
Enum
ただしDataSource
、これを使用して をプログラムで構成することはまだできません。これを と組み合わせて使用する方が適切org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTO
ですが、現在のコードではString
値が必要です (抜粋は から抜粋SessionFactoryBuilderImpl
):
this.schemaAutoTooling = SchemaAutoTooling.interpret( (String) configurationSettings.get( AvailableSettings.HBM2DDL_AUTO ) );
…との両方の内部enum
値は公開されていません。org.hibernate.boot.SchemaAutoTooling
org.hibernate.tool.schema.Action
DataSource
以下に、ギャンビットのおかげで使用するサンプルのプログラム構成(私のSpring Bootアプリケーションで使用)を示します.name().toLowerCase()
が、ダッシュのない値でのみ機能します(create-drop
例ではありません):
@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();
}
上記のすべてで...このプロパティが呼び出されdll.auto
、dll操作(スキーマ/テーブルの作成/ドロップ)のみを制御する必要があることに注意してください。驚くべきことに、dmlにも関係していることがわかりました:update
dml操作であるデータの挿入のみを許可します.
データをメモリ内データベースに入力しようとしたときに、これに引っ掛かりました。のみupdate
動作します。