SchemaTruncator should reimport the load script after truncating
This commit is contained in:
parent
bc4554f86e
commit
479aa10e2f
|
@ -18,7 +18,7 @@ import org.hibernate.query.sql.spi.NamedNativeQueryMemento;
|
|||
import org.hibernate.query.sql.spi.NativeQueryImplementor;
|
||||
|
||||
/**
|
||||
* Keeps details of a named native-sql query
|
||||
* Keeps details of a named native SQL query
|
||||
*
|
||||
* @author Max Andersen
|
||||
* @author Steve Ebersole
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.hibernate.query.spi.QueryImplementor;
|
|||
import org.hibernate.query.sql.internal.NamedNativeQueryMementoImpl;
|
||||
|
||||
/**
|
||||
* Descriptor for a named native query in the run-time environment
|
||||
* Descriptor for a named native query in the runtime environment
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
|
|
@ -51,7 +51,10 @@ public interface SchemaManager {
|
|||
void validateMappedObjects();
|
||||
|
||||
/**
|
||||
* Truncate the database tables mapped by Hibernate entities.
|
||||
* Truncate the database tables mapped by Hibernate entities, and
|
||||
* then re-import initial data from any configured
|
||||
* {@linkplain org.hibernate.cfg.AvailableSettings#JAKARTA_HBM2DDL_LOAD_SCRIPT_SOURCE
|
||||
* load script}.
|
||||
* <p>
|
||||
* Programmatic way to run {@link org.hibernate.tool.schema.spi.SchemaTruncator}.
|
||||
*/
|
||||
|
|
|
@ -12,28 +12,42 @@ import org.hibernate.boot.model.relational.Exportable;
|
|||
import org.hibernate.boot.model.relational.Namespace;
|
||||
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
|
||||
import org.hibernate.boot.model.relational.internal.SqlStringGenerationContextImpl;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.internal.FormatStyle;
|
||||
import org.hibernate.engine.jdbc.internal.Formatter;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.mapping.ForeignKey;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.tool.schema.internal.exec.GenerationTarget;
|
||||
import org.hibernate.tool.schema.internal.exec.JdbcContext;
|
||||
import org.hibernate.tool.schema.internal.exec.ScriptSourceInputFromUrl;
|
||||
import org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl;
|
||||
import org.hibernate.tool.schema.spi.CommandAcceptanceException;
|
||||
import org.hibernate.tool.schema.spi.ContributableMatcher;
|
||||
import org.hibernate.tool.schema.spi.ExecutionOptions;
|
||||
import org.hibernate.tool.schema.spi.SchemaFilter;
|
||||
import org.hibernate.tool.schema.spi.SchemaManagementException;
|
||||
import org.hibernate.tool.schema.spi.SchemaTruncator;
|
||||
import org.hibernate.tool.schema.spi.ScriptSourceInput;
|
||||
import org.hibernate.tool.schema.spi.SqlScriptCommandExtractor;
|
||||
import org.hibernate.tool.schema.spi.TargetDescriptor;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_CHARSET_NAME;
|
||||
import static org.hibernate.cfg.AvailableSettings.HBM2DDL_LOAD_SCRIPT_SOURCE;
|
||||
import static org.hibernate.cfg.AvailableSettings.JAKARTA_HBM2DDL_LOAD_SCRIPT_SOURCE;
|
||||
import static org.hibernate.tool.schema.internal.Helper.interpretScriptSourceSetting;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
|
@ -159,6 +173,10 @@ public class SchemaTruncatorImpl implements SchemaTruncator {
|
|||
enableConstraints( namespace, metadata, formatter, options, sqlStringGenerationContext,
|
||||
contributableInclusionFilter, targets );
|
||||
}
|
||||
|
||||
final SqlScriptCommandExtractor commandExtractor = tool.getServiceRegistry().getService( SqlScriptCommandExtractor.class );
|
||||
final boolean format = Helper.interpretFormattingEnabled( options.getConfigurationValues() );
|
||||
applyImportSources( options, commandExtractor, format, dialect, targets );
|
||||
}
|
||||
|
||||
private void disableConstraints(
|
||||
|
@ -294,4 +312,77 @@ public class SchemaTruncatorImpl implements SchemaTruncator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Woooooo, massive copy/paste from SchemaCreatorImpl!
|
||||
|
||||
private void applyImportSources(
|
||||
ExecutionOptions options,
|
||||
SqlScriptCommandExtractor commandExtractor,
|
||||
boolean format,
|
||||
Dialect dialect,
|
||||
GenerationTarget... targets) {
|
||||
final ServiceRegistry serviceRegistry = tool.getServiceRegistry();
|
||||
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
|
||||
|
||||
// I have had problems applying the formatter to these imported statements.
|
||||
// and legacy SchemaExport did not format them, so doing same here
|
||||
//final Formatter formatter = format ? DDLFormatterImpl.INSTANCE : FormatStyle.NONE.getFormatter();
|
||||
final Formatter formatter = FormatStyle.NONE.getFormatter();
|
||||
|
||||
Object importScriptSetting = options.getConfigurationValues().get( HBM2DDL_LOAD_SCRIPT_SOURCE );
|
||||
if ( importScriptSetting == null ) {
|
||||
importScriptSetting = options.getConfigurationValues().get( JAKARTA_HBM2DDL_LOAD_SCRIPT_SOURCE );
|
||||
}
|
||||
String charsetName = (String) options.getConfigurationValues().get( HBM2DDL_CHARSET_NAME );
|
||||
|
||||
if ( importScriptSetting != null ) {
|
||||
final ScriptSourceInput importScriptInput = interpretScriptSourceSetting( importScriptSetting, classLoaderService, charsetName );
|
||||
final List<String> commands = importScriptInput.extract(
|
||||
reader -> commandExtractor.extractCommands( reader, dialect )
|
||||
);
|
||||
for ( int i = 0; i < commands.size(); i++ ) {
|
||||
applySqlString( commands.get( i ), formatter, options, targets );
|
||||
}
|
||||
}
|
||||
|
||||
final String importFiles = ConfigurationHelper.getString(
|
||||
AvailableSettings.HBM2DDL_IMPORT_FILES,
|
||||
options.getConfigurationValues(),
|
||||
SchemaCreatorImpl.DEFAULT_IMPORT_FILE
|
||||
);
|
||||
|
||||
for ( String currentFile : importFiles.split( "," ) ) {
|
||||
final String resourceName = currentFile.trim();
|
||||
if ( resourceName.isEmpty() ) {
|
||||
//skip empty resource names
|
||||
continue;
|
||||
}
|
||||
final ScriptSourceInput importScriptInput = interpretLegacyImportScriptSetting( resourceName, classLoaderService, charsetName );
|
||||
final List<String> commands = importScriptInput.extract(
|
||||
reader -> commandExtractor.extractCommands( reader, dialect )
|
||||
);
|
||||
for ( int i = 0; i < commands.size(); i++ ) {
|
||||
applySqlString( commands.get( i ), formatter, options, targets );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ScriptSourceInput interpretLegacyImportScriptSetting(
|
||||
String resourceName,
|
||||
ClassLoaderService classLoaderService,
|
||||
String charsetName) {
|
||||
try {
|
||||
final URL resourceUrl = classLoaderService.locateResource( resourceName );
|
||||
if ( resourceUrl == null ) {
|
||||
return ScriptSourceInputNonExistentImpl.INSTANCE;
|
||||
}
|
||||
else {
|
||||
return new ScriptSourceInputFromUrl( resourceUrl, charsetName );
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new SchemaManagementException( "Error resolving legacy import resource : " + resourceName, e );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,13 +4,12 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.orm.test.catalog;
|
||||
package org.hibernate.orm.test.schemamanager;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
|
@ -18,7 +17,6 @@ import org.hibernate.testing.orm.junit.DomainModel;
|
|||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.SkipForDialect;
|
||||
import org.hibernate.tool.schema.spi.SchemaManagementException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -30,11 +28,11 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
@DomainModel(annotatedClasses = {SchemaManagerOracleTest.Book.class, SchemaManagerOracleTest.Author.class})
|
||||
@DomainModel(annotatedClasses = {SchemaManagerDefaultSchemaTest.Book.class, SchemaManagerDefaultSchemaTest.Author.class})
|
||||
@SessionFactory(exportSchema = false)
|
||||
@SkipForDialect(dialectClass = PostgreSQLDialect.class, reason = "doesn't work in the CI")
|
||||
//@SkipForDialect(dialectClass = PostgreSQLDialect.class, reason = "doesn't work in the CI")
|
||||
@RequiresDialectFeature(feature= DialectFeatureChecks.SupportsTruncateTable.class)
|
||||
public class SchemaManagerOracleTest {
|
||||
public class SchemaManagerDefaultSchemaTest {
|
||||
|
||||
@BeforeEach
|
||||
public void clean(SessionFactoryScope scope) {
|
||||
|
@ -45,7 +43,7 @@ public class SchemaManagerOracleTest {
|
|||
return s.createQuery("select count(*) from BookForTesting", Long.class).getSingleResult();
|
||||
}
|
||||
|
||||
@Test public void test0(SessionFactoryScope scope) {
|
||||
@Test public void testExportValidateTruncateDrop(SessionFactoryScope scope) {
|
||||
SessionFactoryImplementor factory = scope.getSessionFactory();
|
||||
factory.getSchemaManager().exportMappedObjects(true);
|
||||
scope.inTransaction( s -> s.persist( new Book() ) );
|
|
@ -4,13 +4,12 @@
|
|||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.orm.test.catalog;
|
||||
package org.hibernate.orm.test.schemamanager;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.OracleDialect;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
|
@ -26,6 +25,7 @@ import org.hibernate.tool.schema.spi.SchemaManagementException;
|
|||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.DEFAULT_SCHEMA;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
@ -33,12 +33,12 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
@DomainModel(annotatedClasses = {SchemaManagerTest.Book.class, SchemaManagerTest.Author.class})
|
||||
@DomainModel(annotatedClasses = {SchemaManagerExplicitSchemaTest.Book.class, SchemaManagerExplicitSchemaTest.Author.class})
|
||||
@SessionFactory(exportSchema = false)
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.DEFAULT_SCHEMA, value = "schema_manager_test"))
|
||||
@ServiceRegistry(settings = @Setting(name = DEFAULT_SCHEMA, value = "schema_manager_test"))
|
||||
@SkipForDialect(dialectClass = OracleDialect.class, reason = "Oracle tests run in the DBO schema")
|
||||
@RequiresDialectFeature(feature= DialectFeatureChecks.SupportsTruncateTable.class)
|
||||
public class SchemaManagerTest {
|
||||
public class SchemaManagerExplicitSchemaTest {
|
||||
|
||||
@BeforeEach
|
||||
public void clean(SessionFactoryScope scope) {
|
||||
|
@ -49,7 +49,7 @@ public class SchemaManagerTest {
|
|||
return s.createQuery("select count(*) from BookForTesting", Long.class).getSingleResult();
|
||||
}
|
||||
|
||||
@Test public void test0(SessionFactoryScope scope) {
|
||||
@Test public void testExportValidateTruncateDrop(SessionFactoryScope scope) {
|
||||
SessionFactoryImplementor factory = scope.getSessionFactory();
|
||||
factory.getSchemaManager().exportMappedObjects(true);
|
||||
scope.inTransaction( s -> s.persist( new Book() ) );
|
||||
|
@ -69,7 +69,7 @@ public class SchemaManagerTest {
|
|||
|
||||
@Entity(name="BookForTesting")
|
||||
static class Book {
|
||||
@Id String isbn = "xyz123";
|
||||
@Id String isbn = "9781932394153";
|
||||
String title = "Hibernate in Action";
|
||||
@ManyToOne(cascade = CascadeType.PERSIST)
|
||||
Author author = new Author();
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.orm.test.schemamanager;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SessionImplementor;
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.JAKARTA_HBM2DDL_LOAD_SCRIPT_SOURCE;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
@DomainModel(annotatedClasses = {SchemaManagerLoadScriptTest.Book.class, SchemaManagerLoadScriptTest.Author.class})
|
||||
@SessionFactory(exportSchema = false)
|
||||
@ServiceRegistry(settings = @Setting(name = JAKARTA_HBM2DDL_LOAD_SCRIPT_SOURCE,
|
||||
value = "org/hibernate/orm/test/schemamanager/data.sql"))
|
||||
@RequiresDialectFeature(feature= DialectFeatureChecks.SupportsTruncateTable.class)
|
||||
public class SchemaManagerLoadScriptTest {
|
||||
|
||||
@BeforeEach
|
||||
public void clean(SessionFactoryScope scope) {
|
||||
scope.getSessionFactory().getSchemaManager().dropMappedObjects(true);
|
||||
}
|
||||
|
||||
private Long countBooks(SessionImplementor s) {
|
||||
return s.createQuery("select count(*) from Book", Long.class).getSingleResult();
|
||||
}
|
||||
|
||||
private Long countAuthors(SessionImplementor s) {
|
||||
return s.createQuery("select count(*) from Author", Long.class).getSingleResult();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportValidateTruncateDrop(SessionFactoryScope scope) {
|
||||
SessionFactoryImplementor factory = scope.getSessionFactory();
|
||||
factory.getSchemaManager().exportMappedObjects(true);
|
||||
factory.getSchemaManager().validateMappedObjects();
|
||||
Author author = new Author(); author.name = "Steve Ebersole";
|
||||
scope.inTransaction( s -> s.persist(author) );
|
||||
scope.inTransaction( s -> assertEquals( 1, countBooks(s) ) );
|
||||
scope.inTransaction( s -> assertEquals( 3, countAuthors(s) ) );
|
||||
factory.getSchemaManager().truncateMappedObjects();
|
||||
scope.inTransaction( s -> assertEquals( 2, countAuthors(s) ) );
|
||||
factory.getSchemaManager().dropMappedObjects(true);
|
||||
}
|
||||
|
||||
@Entity(name="Book") @Table(name="Books")
|
||||
static class Book {
|
||||
@Id
|
||||
String isbn;
|
||||
String title;
|
||||
}
|
||||
|
||||
@Entity(name="Author") @Table(name="Authors")
|
||||
static class Author {
|
||||
@Id String name;
|
||||
@ManyToMany @JoinTable(name = "BooksByAuthor")
|
||||
public Set<Book> books;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
insert into Books (isbn, title) values ('9781932394887','Java Persistence with Hibernate')
|
||||
insert into Authors (name) values ('Gavin King')
|
||||
insert into Authors (name) values ('Christian Bauer')
|
||||
insert into BooksByAuthor (books_isbn, Author_name) values ('9781932394887','Gavin King')
|
||||
insert into BooksByAuthor (books_isbn, Author_name) values ('9781932394887','Christian Bauer')
|
Loading…
Reference in New Issue