Configuration.generateSchemaCreationScript()在Hibernate 5中的位置

在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会再次中断,因此请务必选择合适的版本:

Hibernate 5.2:

 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()); 

Hibernate 5.2(没有警告):

以上将产生一些令人讨厌的警告,可以忽略:

Okt 20,2016 2:57:16 PM org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator initiateService
警告:HHH000181:假设应用程序将提供连接,则没有遇到任何适当的连接提供程序
Okt 20,2016 2:57:16 PM org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator initiateService
警告:HHH000342:无法获取与查询元数据的连接:应用程序必须提供JDBC连接

…或者你通过将以下ConnectionProvider入侵到设置中来解决它们(在我看来不应该要求它)

  .applySetting(AvailableSettings.CONNECTION_PROVIDER, new ConnectionProvider() { @Override public boolean isUnwrappableAs(Class unwrapType) { return false; } @Override public  T unwrap(Class 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; } }) 

Hibernate 5.0:

 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); 

hibernate4:

提醒一下,这是在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中提供了新SchemaExport初始化的一个示例:

 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 ); 

当然,您可以根据自己的需要进行自定义。

新的引导程序API允许进行许多自定义,但假设您不需要这些自定义项,最短的调用将类似于此,应用服务注册表的默认值和所有设置:

 Metadata metadata = new MetadataSources() .addAnnotatedClass( MyEntity.class ) .build(); new SchemaExport( (MetadataImplementor) metadata ) .setOutputFile( "my-statements.ddl" ) .create( Target.NONE ); 

更新:提供应用配置属性的示例

有几种方法可以为连接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(); 

如果一个人正在使用JPA 2.1+ – 有一个非常简单的内置可能性来生成ddl。 只需设置以下jpa属性,即可创建ddl文件。 使用spring boot,可以使用这些特定的配置选项编写一个单独的主类。

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+的Spring Boot

schemagenerator.properties(放入资源文件夹):

 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(); } }