diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NamedNativeQueryMementoImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NamedNativeQueryMementoImpl.java
index e3db8e30d8..66e9a2559d 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NamedNativeQueryMementoImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NamedNativeQueryMementoImpl.java
@@ -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
diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java
index 6a32c81f51..b7b08c9c31 100644
--- a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java
+++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/NamedNativeQueryMemento.java
@@ -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
*/
diff --git a/hibernate-core/src/main/java/org/hibernate/relational/SchemaManager.java b/hibernate-core/src/main/java/org/hibernate/relational/SchemaManager.java
index 5ade9bf6b9..f72aa48b76 100644
--- a/hibernate-core/src/main/java/org/hibernate/relational/SchemaManager.java
+++ b/hibernate-core/src/main/java/org/hibernate/relational/SchemaManager.java
@@ -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}.
*
* Programmatic way to run {@link org.hibernate.tool.schema.spi.SchemaTruncator}.
*/
diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaTruncatorImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaTruncatorImpl.java
index 6cf7ce57b2..b70f6cead5 100644
--- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaTruncatorImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaTruncatorImpl.java
@@ -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 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 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 );
+ }
+ }
+
}
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/catalog/SchemaManagerOracleTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemamanager/SchemaManagerDefaultSchemaTest.java
similarity index 85%
rename from hibernate-core/src/test/java/org/hibernate/orm/test/catalog/SchemaManagerOracleTest.java
rename to hibernate-core/src/test/java/org/hibernate/orm/test/schemamanager/SchemaManagerDefaultSchemaTest.java
index a7cacfe473..2cc1a446f1 100644
--- a/hibernate-core/src/test/java/org/hibernate/orm/test/catalog/SchemaManagerOracleTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemamanager/SchemaManagerDefaultSchemaTest.java
@@ -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 .
*/
-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() ) );
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/catalog/SchemaManagerTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemamanager/SchemaManagerExplicitSchemaTest.java
similarity index 85%
rename from hibernate-core/src/test/java/org/hibernate/orm/test/catalog/SchemaManagerTest.java
rename to hibernate-core/src/test/java/org/hibernate/orm/test/schemamanager/SchemaManagerExplicitSchemaTest.java
index 932dc4f721..9564e92077 100644
--- a/hibernate-core/src/test/java/org/hibernate/orm/test/catalog/SchemaManagerTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemamanager/SchemaManagerExplicitSchemaTest.java
@@ -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 .
*/
-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();
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemamanager/SchemaManagerLoadScriptTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemamanager/SchemaManagerLoadScriptTest.java
new file mode 100644
index 0000000000..e96776ee11
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemamanager/SchemaManagerLoadScriptTest.java
@@ -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 .
+ */
+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 books;
+ }
+}
diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemamanager/data.sql b/hibernate-core/src/test/java/org/hibernate/orm/test/schemamanager/data.sql
new file mode 100644
index 0000000000..f59cdd1e73
--- /dev/null
+++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemamanager/data.sql
@@ -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')