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