Где ConfigurationGenerateSchemaCreationScript () переместился в Hibernate 5
В Hibernate 4.x я использовал для генерации и экспорта схемы, как определено в аннотированных сущностях, следующим образом (используя Spring для поиска аннотированных объектов в пути classа):
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)
теперь устарел
Я действительно не нашел никаких очевидных ссылок на это изменение в руководстве по миграции, кроме:
- Получение cmake для создания из исходного кода без обертывания скриптов?
- Struts 2: для пространства имен не отображается действие
- Настройка кластера Hadoop - java.net.ConnectException: соединение отклонено
- @Value не разрешается при использовании annotations @PropertySource. Как настроить PropertySourcesPlaceholderConfigurer?
- Загрузка пользовательских файлов конфигурации
Из конфигурации было удалено несколько методов
Каков правильный способ создания и экспорта базы данных на существующее соединение JDBC с Hibernate 5.0 на основе набора аннотированных объектов? (Чистые решения на основе JPA тоже прекрасны)
(заметьте, просто удаление вызова generateSchemaCreationScript()
похоже, работает, но я бы предпочел убедиться, что это правильно)
- Spring Java Config vs Jboss 7
- Что я должен установить JAVA_HOME на OSX
- Как показать номера строк в Eclipse?
- Angular2 Anchronronous bootstrapping с внешним конфигурационным файлом json
- Конфигурация DI vs xml на основе аннотаций Spring?
- Как просмотреть настройки конфигурации из Symfony2 config.yml?
- Как правильно инициализировать log4j?
- Создание нескольких разделов HTTP в Spring Security Конфигурация Java
Благодаря ответам Влада и Гуннара мне удалось найти путь через новый 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 вечера org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator initiateService
WARN: HHH000181: Отсутствует соответствующий поставщик соединения, предполагая, что приложение будет поставлять соединения
Okt 20, 2016 2:57:16 вечера org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator initiateService
WARN: 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);
Hibernate 4:
Напомним, вот как это работает в 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 );
Конечно, вы можете настроить его в соответствии с вашими потребностями.
Новый загрузочный 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. С весенней загрузкой можно написать отдельный основной class с определенными настройками.
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 (помещать в папку ресурсов):
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 SchemaGenerator:
public class SchemaGenerator { public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, new String[]{"--spring.config.name=schemagenerator"}).close(); } }