Hibernate 4.xでは、アノテーション付きエンティティで定義されたスキーマを次のように生成およびエクスポートしていました(Springを使用してクラスパス上のアノテーション付きエンティティを検索しました)。
_Connection connection =
DriverManager.getConnection("jdbc:h2:mem:jooq-meta-extensions", "sa", "");
Configuration configuration = new Configuration()
.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
// [...] adding annotated classes to Configuration here...
configuration.generateSchemaCreationScript(
Dialect.getDialect(configuration.getProperties()));
SchemaExport export = new SchemaExport(configuration, connection);
export.create(true, true);
_
これはHibernate 5.0では機能しなくなりました。
Configuration.generateSchemaCreationScript()
存在しませんSchemaExport(configuration, connection)
コンストラクタは廃止されました移行ガイド に、この変更に関する明確な参照は実際には見つかりませんでした。
かなりの数のメソッドが構成から削除されました
注釈付きエンティティのセットに基づいてHibernate 5.0でデータベースを生成およびエクスポートする正しい方法は何ですか既存のJDBC接続上? (純粋なJPAベースのソリューションも問題ありません)
(注、generateSchemaCreationScript()
の呼び出しを削除するだけで機能するようですが、これを正しく行うことをお勧めします)
Vlad および Gunnar による回答のおかげで、新しい構成APIを使用して、次のような同等のエクスポートロジックを作成することができました。もちろん、歴史はこのAPIが再び壊れることを示しているので、適切なバージョンを選択するようにしてください:
MetadataSources metadata = new MetadataSources(
new StandardServiceRegistryBuilder()
.applySetting("hibernate.dialect", "org.hibernate.dialect.H2Dialect")
.applySetting("javax.persistence.schema-generation-connection", connection)
.build());
// [...] adding annotated classes to metadata here...
metadata.addAnnotatedClass(...);
SchemaExport export = new SchemaExport();
export.create(EnumSet.of(TargetType.DATABASE), metadata.buildMetadata());
上記はいくつかの厄介な警告を生成しますが、どちらか無視することができます:
Okt 20、2016 2:57:16 PM org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator beginService
警告:HHH000181:アプリケーションが接続を提供すると想定して、適切な接続プロバイダーが見つかりません
2016年10月20日2:57:16 PM org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator initializeService
警告:HHH000342:クエリメタデータへの接続を取得できませんでした:アプリケーションはJDBC接続を提供する必要があります
...または、次のConnectionProvider
を設定にハッキングすることで回避します(私の意見では必要ありません)
.applySetting(AvailableSettings.CONNECTION_PROVIDER, new ConnectionProvider() {
@Override
public boolean isUnwrappableAs(Class unwrapType) {
return false;
}
@Override
public <T> T unwrap(Class<T> unwrapType) {
return null;
}
@Override
public Connection getConnection() {
return connection; // Interesting part here
}
@Override
public void closeConnection(Connection conn) throws SQLException {}
@Override
public boolean supportsAggressiveRelease() {
return true;
}
})
MetadataSources metadata = new MetadataSources(
new StandardServiceRegistryBuilder()
.applySetting("hibernate.dialect", "org.hibernate.dialect.H2Dialect")
.build());
// [...] adding annotated classes to metadata here...
metadata.addAnnotatedClass(...);
SchemaExport export = new SchemaExport(
(MetadataImplementor) metadata.buildMetadata(),
connection // pre-configured Connection here
);
export.create(true, true);
注意として、これがHibernate 4でどのように機能したかを示します。
Configuration configuration = new Configuration()
.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
// [...] adding annotated classes to metadata here...
configuration.addAnnotatedClass(...);
configuration.generateSchemaCreationScript(
Dialect.getDialect(configuration.getProperties()));
SchemaExport export = new SchemaExport(configuration, connection);
export.create(true, true);
新しいSchemaExport
初期化の一例は SchemaExportTask にあります。
final BootstrapServiceRegistry bsr = new BootstrapServiceRegistryBuilder().build();
final MetadataSources metadataSources = new MetadataSources( bsr );
final StandardServiceRegistryBuilder ssrBuilder = new StandardServiceRegistryBuilder( bsr );
if ( configurationFile != null ) {
ssrBuilder.configure( configurationFile );
}
if ( propertiesFile != null ) {
ssrBuilder.loadProperties( propertiesFile );
}
ssrBuilder.applySettings( getProject().getProperties() );
for ( String fileName : getFiles() ) {
if ( fileName.endsWith(".jar") ) {
metadataSources.addJar( new File( fileName ) );
}
else {
metadataSources.addFile( fileName );
}
}
final StandardServiceRegistryImpl ssr = (StandardServiceRegistryImpl) ssrBuilder.build();
final MetadataBuilder metadataBuilder = metadataSources.getMetadataBuilder( ssr );
ClassLoaderService classLoaderService = bsr.getService( ClassLoaderService.class );
if ( implicitNamingStrategy != null ) {
metadataBuilder.applyImplicitNamingStrategy(
(ImplicitNamingStrategy) classLoaderService.classForName( implicitNamingStrategy ).newInstance()
);
}
if ( physicalNamingStrategy != null ) {
metadataBuilder.applyPhysicalNamingStrategy(
(PhysicalNamingStrategy) classLoaderService.classForName( physicalNamingStrategy ).newInstance()
);
}
return new SchemaExport( (MetadataImplementor) metadataBuilder.build() )
.setHaltOnError( haltOnError )
.setOutputFile( outputFile.getPath() )
.setDelimiter( delimiter );
もちろん、必要に応じてカスタマイズすることもできます。
新しいbootstrap APIでは多くのカスタマイズが可能ですが、それらを必要としない場合、最短の呼び出しは次のようになります。サービスレジストリとすべての設定にデフォルト値を適用します。
Metadata metadata = new MetadataSources()
.addAnnotatedClass( MyEntity.class )
.build();
new SchemaExport( (MetadataImplementor) metadata )
.setOutputFile( "my-statements.ddl" )
.create( Target.NONE );
pdate:構成プロパティの適用例を提供
接続URL、方言などのプロパティを挿入する方法はいくつかあります。ファイルhibernate.propertiesを提供するか、必要な設定でカスタマイズされたサービスレジストリを使用できます。
StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.applySetting( "hibernate.connection.url", "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1" )
.build();
Metadata metadata = new MetadataSources( registry )
.build();
Hibernate 5.4.9.Finalを使用して、この方法でエクスポートしました。
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;
import Java.util.EnumSet;
public class ExportSchema {
public static void main(String[] args) {
final StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySetting("hibernate.dialect", "org.hibernate.dialect.H2Dialect")
.build();
final Metadata metadata = new MetadataSources(serviceRegistry)
.addAnnotatedClass(...)
.buildMetadata();
new SchemaExport()
.setFormat(true)
.setDelimiter(";")
.setOutputFile("schema.sql")
.execute(EnumSet.of(TargetType.SCRIPT), SchemaExport.Action.CREATE, metadata);
}
}
JPA 2.1+を使用している場合-ddlを生成する非常に単純な組み込みの可能性があります。以下のjpaプロパティを設定するだけで、ddlファイルが作成されます。スプリングブートを使用すると、特定の構成オプションを使用して別のメインクラスを作成できます。
JPA 2.1 +
javax.persistence.schema-generation.scripts.action=drop-and-create
javax.persistence.schema-generation.scripts.create-target=create.ddl
javax.persistence.schema-generation.scripts.drop-target=drop.ddl
JPA 2.1以降のスプリングブート
schemagenerator.properties(resourcesフォルダーに配置):
spring.jpa.properties.javax.persistence.schema-generation.scripts.action=drop-and-create
spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.ddl
spring.jpa.properties.javax.persistence.schema-generation.scripts.drop-target=drop.ddl
flyway.enabled=false // in case you use flyway for db maintenance
Spring Boot SchemaGenerator:
public class SchemaGenerator {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, new String[]{"--spring.config.name=schemagenerator"}).close();
}
}