diff --git a/documentation/src/test/java/org/hibernate/userguide/mapping/embeddable/NestedStructEmbeddableTest.java b/documentation/src/test/java/org/hibernate/userguide/mapping/embeddable/NestedStructEmbeddableTest.java index 51c01c53cd..492dc0293c 100644 --- a/documentation/src/test/java/org/hibernate/userguide/mapping/embeddable/NestedStructEmbeddableTest.java +++ b/documentation/src/test/java/org/hibernate/userguide/mapping/embeddable/NestedStructEmbeddableTest.java @@ -76,6 +76,8 @@ public class NestedStructEmbeddableTest extends BaseSessionFactoryFunctionalTest // otherwise we might run into ORA-21700: object does not exist or is marked for delete // because the JDBC connection or database session caches something that should have been invalidated ssrBuilder.applySetting( AvailableSettings.CONNECTION_PROVIDER, DriverManagerConnectionProviderImpl.class.getName() ); + // Don't reorder columns in the types here to avoid the need to rewrite the test + ssrBuilder.applySetting( AvailableSettings.COLUMN_ORDERING_STRATEGY, "legacy" ); return super.produceServiceRegistry( ssrBuilder ); } @@ -561,6 +563,7 @@ public class NestedStructEmbeddableTest extends BaseSessionFactoryFunctionalTest @Test @SkipForDialect(dialectClass = PostgreSQLDialect.class, majorVersion = 10, reason = "Procedures were only introduced in version 11") + @SkipForDialect(dialectClass = PostgresPlusDialect.class, majorVersion = 10, reason = "Procedures were only introduced in version 11") @SkipForDialect(dialectClass = DB2Dialect.class, reason = "DB2 does not support struct types in procedures") public void testProcedure() { sessionFactoryScope().inTransaction( diff --git a/documentation/src/test/java/org/hibernate/userguide/mapping/embeddable/StructEmbeddableTest.java b/documentation/src/test/java/org/hibernate/userguide/mapping/embeddable/StructEmbeddableTest.java index b550293dc2..dbcc17153c 100644 --- a/documentation/src/test/java/org/hibernate/userguide/mapping/embeddable/StructEmbeddableTest.java +++ b/documentation/src/test/java/org/hibernate/userguide/mapping/embeddable/StructEmbeddableTest.java @@ -76,6 +76,8 @@ public class StructEmbeddableTest extends BaseSessionFactoryFunctionalTest { // otherwise we might run into ORA-21700: object does not exist or is marked for delete // because the JDBC connection or database session caches something that should have been invalidated ssrBuilder.applySetting( AvailableSettings.CONNECTION_PROVIDER, DriverManagerConnectionProviderImpl.class.getName() ); + // Don't reorder columns in the types here to avoid the need to rewrite the test + ssrBuilder.applySetting( AvailableSettings.COLUMN_ORDERING_STRATEGY, "legacy" ); return super.produceServiceRegistry( ssrBuilder ); } @@ -521,6 +523,7 @@ public class StructEmbeddableTest extends BaseSessionFactoryFunctionalTest { @Test @SkipForDialect(dialectClass = PostgreSQLDialect.class, majorVersion = 10, reason = "Procedures were only introduced in version 11") + @SkipForDialect(dialectClass = PostgresPlusDialect.class, majorVersion = 10, reason = "Procedures were only introduced in version 11") @SkipForDialect(dialectClass = DB2Dialect.class, reason = "DB2 does not support struct types in procedures") public void testProcedure() { sessionFactoryScope().inTransaction( diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgresPlusLegacyDialect.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgresPlusLegacyDialect.java new file mode 100644 index 0000000000..03c6a330b3 --- /dev/null +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgresPlusLegacyDialect.java @@ -0,0 +1,115 @@ +/* + * 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.community.dialect; + +import java.sql.CallableStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +import org.hibernate.dialect.DatabaseVersion; +import org.hibernate.dialect.function.CommonFunctionFactory; +import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo; +import org.hibernate.query.spi.QueryEngine; +import org.hibernate.query.sqm.CastType; +import org.hibernate.query.sqm.TemporalUnit; + +import jakarta.persistence.TemporalType; + +import static org.hibernate.query.sqm.TemporalUnit.DAY; + +/** + * An SQL dialect for Postgres Plus + * + * @author Jim Mlodgenski + */ +public class PostgresPlusLegacyDialect extends PostgreSQLLegacyDialect { + + /** + * Constructs a PostgresPlusDialect + */ + public PostgresPlusLegacyDialect() { + super(); + } + + public PostgresPlusLegacyDialect(DialectResolutionInfo info) { + super( info ); + } + + public PostgresPlusLegacyDialect(DatabaseVersion version) { + super( version ); + } + + @Override + public void initializeFunctionRegistry(QueryEngine queryEngine) { + super.initializeFunctionRegistry( queryEngine ); + + CommonFunctionFactory functionFactory = new CommonFunctionFactory(queryEngine); + functionFactory.soundex(); + functionFactory.rownumRowid(); + functionFactory.sysdate(); + functionFactory.systimestamp(); + +// queryEngine.getSqmFunctionRegistry().register( "coalesce", new NvlCoalesceEmulation() ); + + } + + @Override + public String castPattern(CastType from, CastType to) { + if ( to == CastType.STRING ) { + switch ( from ) { + case DATE: + return "to_char(?1,'YYYY-MM-DD')"; + case TIME: + return "to_char(?1,'HH24:MI:SS')"; + case TIMESTAMP: + return "to_char(?1,'YYYY-MM-DD HH24:MI:SS.FF9')"; + case OFFSET_TIMESTAMP: + return "to_char(?1,'YYYY-MM-DD HH24:MI:SS.FF9TZH:TZM')"; + case ZONE_TIMESTAMP: + return "to_char(?1,'YYYY-MM-DD HH24:MI:SS.FF9 TZR')"; + } + } + return super.castPattern( from, to ); + } + + @Override + public String currentTimestamp() { + return "current_timestamp"; + } + + @Override + public String timestampdiffPattern(TemporalUnit unit, TemporalType fromTemporalType, TemporalType toTemporalType) { + if ( toTemporalType != TemporalType.TIMESTAMP && fromTemporalType != TemporalType.TIMESTAMP && unit == DAY ) { + // special case: subtraction of two dates results in an INTERVAL on Postgres Plus + // because there is no date type i.e. without time for Oracle compatibility + final StringBuilder pattern = new StringBuilder(); + extractField( pattern, DAY, fromTemporalType, toTemporalType, unit ); + return pattern.toString(); + } + return super.timestampdiffPattern( unit, fromTemporalType, toTemporalType ); + } + + @Override + public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException { + statement.registerOutParameter( col, Types.REF ); + col++; + return col; + } + + @Override + public ResultSet getResultSet(CallableStatement ps) throws SQLException { + ps.execute(); + return (ResultSet) ps.getObject( 1 ); + } + + @Override + public String getSelectGUIDString() { + return "select uuid_generate_v1"; + } + +} diff --git a/hibernate-core/hibernate-core.gradle b/hibernate-core/hibernate-core.gradle index 7a2c408de2..01d0865e77 100644 --- a/hibernate-core/hibernate-core.gradle +++ b/hibernate-core/hibernate-core.gradle @@ -283,7 +283,7 @@ if ( gradle.ext.javaVersions.test.release.asInt() >= 17 && gradle.ext.javaToolch } // We execute the Java 17 tests in a custom test task - task java17Test(type: Test) { + task testJava17(type: Test) { javaLauncher = javaToolchains.launcherFor { languageVersion = gradle.ext.javaVersions.test.launcher } @@ -300,5 +300,5 @@ if ( gradle.ext.javaVersions.test.release.asInt() >= 17 && gradle.ext.javaToolch testClasses.dependsOn compileTestJava17Java // And run this as part of the check task by default - check.dependsOn java17Test + check.dependsOn testJava17 } \ No newline at end of file diff --git a/hibernate-core/src/main/java/org/hibernate/boot/MetadataBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/MetadataBuilder.java index 8bdb187306..8778b77a90 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/MetadataBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/MetadataBuilder.java @@ -16,6 +16,7 @@ import org.hibernate.boot.model.convert.spi.ConverterDescriptor; import org.hibernate.boot.model.naming.ImplicitNamingStrategy; import org.hibernate.boot.model.naming.PhysicalNamingStrategy; import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject; +import org.hibernate.boot.model.relational.ColumnOrderingStrategy; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cfg.MetadataSourceType; import org.hibernate.metamodel.CollectionClassification; @@ -93,6 +94,20 @@ public interface MetadataBuilder { */ MetadataBuilder applyPhysicalNamingStrategy(PhysicalNamingStrategy namingStrategy); + /** + * Specify the {@link ColumnOrderingStrategy}. + *

+ * Its default is defined by the {@value org.hibernate.cfg.AvailableSettings#COLUMN_ORDERING_STRATEGY} + * setting if using property-based configuration. + * + * @param columnOrderingStrategy The {@link ColumnOrderingStrategy} + * + * @return {@code this}, for method chaining + * + * @see org.hibernate.cfg.AvailableSettings#IMPLICIT_NAMING_STRATEGY + */ + MetadataBuilder applyColumnOrderingStrategy(ColumnOrderingStrategy columnOrderingStrategy); + /** * Specify the second-level cache mode. *

diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java index 39abc0de66..475388c66c 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java @@ -11,7 +11,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; @@ -78,7 +77,6 @@ import org.hibernate.cfg.SecondaryTableFromAnnotationSecondPass; import org.hibernate.cfg.SecondaryTableSecondPass; import org.hibernate.cfg.SetBasicValueTypeSecondPass; import org.hibernate.cfg.UniqueConstraintHolder; -import org.hibernate.cfg.annotations.BasicValueBinder; import org.hibernate.cfg.annotations.NamedEntityGraphDefinition; import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.FilterDefinition; @@ -86,7 +84,6 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.collections.CollectionHelper; -import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.Collection; import org.hibernate.mapping.Column; import org.hibernate.mapping.Component; @@ -104,7 +101,6 @@ import org.hibernate.mapping.RootClass; import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Table; import org.hibernate.mapping.UniqueKey; -import org.hibernate.mapping.Value; import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.spi.EmbeddableInstantiator; import org.hibernate.query.named.NamedObjectRepository; @@ -243,6 +239,11 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector, throw new UnsupportedOperationException(); } + @Override + public void orderColumns(boolean forceOrdering) { + // nothing to do + } + @Override public void validate() throws MappingException { // nothing to do @@ -2308,7 +2309,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector, */ public MetadataImpl buildMetadataInstance(MetadataBuildingContext buildingContext) { processSecondPasses( buildingContext ); - processExportableProducers( ); + processExportableProducers(); try { return new MetadataImpl( diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataBuilderImpl.java index 062e760a1a..b9f8954282 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataBuilderImpl.java @@ -39,6 +39,8 @@ import org.hibernate.boot.model.naming.PhysicalNamingStrategy; import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl; import org.hibernate.boot.model.process.spi.MetadataBuildingProcess; import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject; +import org.hibernate.boot.model.relational.ColumnOrderingStrategy; +import org.hibernate.boot.model.relational.ColumnOrderingStrategyStandard; import org.hibernate.boot.registry.BootstrapServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; @@ -180,6 +182,12 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont return this; } + @Override + public MetadataBuilder applyColumnOrderingStrategy(ColumnOrderingStrategy columnOrderingStrategy) { + this.options.columnOrderingStrategy = columnOrderingStrategy; + return this; + } + @Override public MetadataBuilder applySharedCacheMode(SharedCacheMode sharedCacheMode) { this.options.sharedCacheMode = sharedCacheMode; @@ -548,6 +556,7 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont private ImplicitNamingStrategy implicitNamingStrategy; private PhysicalNamingStrategy physicalNamingStrategy; + private ColumnOrderingStrategy columnOrderingStrategy; private SharedCacheMode sharedCacheMode; private final AccessType defaultCacheAccessType; @@ -692,6 +701,21 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont PhysicalNamingStrategyStandardImpl.INSTANCE ); + this.columnOrderingStrategy = strategySelector.resolveDefaultableStrategy( + ColumnOrderingStrategy.class, + configService.getSettings().get( AvailableSettings.COLUMN_ORDERING_STRATEGY ), + new Callable<>() { + @Override + public ColumnOrderingStrategy call() { + return strategySelector.resolveDefaultableStrategy( + ColumnOrderingStrategy.class, + "default", + ColumnOrderingStrategyStandard.INSTANCE + ); + } + } + ); + this.sourceProcessOrdering = resolveInitialSourceProcessOrdering( configService ); this.useNationalizedCharacterData = configService.getSetting( @@ -823,6 +847,11 @@ public class MetadataBuilderImpl implements MetadataBuilderImplementor, TypeCont return physicalNamingStrategy; } + @Override + public ColumnOrderingStrategy getColumnOrderingStrategy() { + return columnOrderingStrategy; + } + @Override public SharedCacheMode getSharedCacheMode() { return sharedCacheMode; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java index 8b443c1538..1f3d4a2c5d 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java @@ -24,6 +24,8 @@ import org.hibernate.SessionFactory; import org.hibernate.boot.SessionFactoryBuilder; import org.hibernate.boot.model.IdentifierGeneratorDefinition; import org.hibernate.boot.model.TypeDefinition; +import org.hibernate.boot.model.relational.ColumnOrderingStrategy; +import org.hibernate.boot.model.relational.ColumnOrderingStrategyLegacy; import org.hibernate.boot.model.relational.Database; import org.hibernate.boot.model.relational.Namespace; import org.hibernate.boot.model.relational.Sequence; @@ -48,12 +50,17 @@ import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventType; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.mapping.Collection; +import org.hibernate.mapping.Column; import org.hibernate.mapping.Component; import org.hibernate.mapping.FetchProfile; +import org.hibernate.mapping.ForeignKey; import org.hibernate.mapping.MappedSuperclass; import org.hibernate.mapping.PersistentClass; +import org.hibernate.mapping.PrimaryKey; import org.hibernate.mapping.Property; import org.hibernate.mapping.Table; +import org.hibernate.mapping.UniqueKey; +import org.hibernate.mapping.UserDefinedType; import org.hibernate.procedure.spi.NamedCallableQueryMemento; import org.hibernate.query.internal.NamedObjectRepositoryImpl; import org.hibernate.query.named.NamedObjectRepository; @@ -61,6 +68,8 @@ import org.hibernate.query.sql.spi.NamedNativeQueryMemento; import org.hibernate.query.sqm.function.SqmFunctionDescriptor; import org.hibernate.query.sqm.spi.NamedSqmQueryMemento; import org.hibernate.service.spi.ServiceRegistryImplementor; +import org.hibernate.tool.schema.Action; +import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator; import org.hibernate.type.spi.TypeConfiguration; /** @@ -370,6 +379,120 @@ public class MetadataImpl implements MetadataImplementor, Serializable { return map; } + @Override + public void orderColumns(boolean forceOrdering) { + final ColumnOrderingStrategy columnOrderingStrategy = metadataBuildingOptions.getColumnOrderingStrategy(); + if ( columnOrderingStrategy == ColumnOrderingStrategyLegacy.INSTANCE ) { + // No need to order columns when using the no-op strategy + return; + } + + final boolean shouldOrderTableColumns = forceOrdering || shouldOrderTableColumns(); + + for ( Namespace namespace : database.getNamespaces() ) { + if ( shouldOrderTableColumns ) { + for ( Table table : namespace.getTables() ) { + final List tableColumns = columnOrderingStrategy.orderTableColumns( table, this ); + if ( tableColumns != null ) { + table.reorderColumns( tableColumns ); + } + final PrimaryKey primaryKey = table.getPrimaryKey(); + if ( primaryKey != null && primaryKey.getColumns() + .size() > 1 && primaryKey.getOriginalOrder() == null ) { + final List primaryKeyColumns = columnOrderingStrategy.orderConstraintColumns( + primaryKey, + this + ); + if ( primaryKeyColumns != null ) { + primaryKey.reorderColumns( primaryKeyColumns ); + } + } + for ( UniqueKey uniqueKey : table.getUniqueKeys().values() ) { + if ( uniqueKey.getColumns().size() > 1 ) { + final List uniqueKeyColumns = columnOrderingStrategy.orderConstraintColumns( + uniqueKey, + this + ); + if ( uniqueKeyColumns != null ) { + uniqueKey.getColumns().clear(); + uniqueKey.getColumns().addAll( uniqueKeyColumns ); + } + } + } + for ( ForeignKey foreignKey : table.getForeignKeys().values() ) { + final List columns = foreignKey.getColumns(); + if ( columns.size() > 1 ) { + if ( foreignKey.getReferencedColumns().isEmpty() ) { + final PrimaryKey foreignKeyTargetPrimaryKey = foreignKey.getReferencedTable() + .getPrimaryKey(); + // Make sure we order the columns of the primary key first, + // so that foreign key ordering can rely on this + if ( foreignKeyTargetPrimaryKey.getOriginalOrder() == null ) { + final List primaryKeyColumns = columnOrderingStrategy.orderConstraintColumns( + foreignKeyTargetPrimaryKey, + this + ); + if ( primaryKeyColumns != null ) { + foreignKeyTargetPrimaryKey.reorderColumns( primaryKeyColumns ); + } + } + + // Patch up the order of foreign keys based on new order of the target primary key + final int[] originalPrimaryKeyOrder = foreignKeyTargetPrimaryKey.getOriginalOrder(); + if ( originalPrimaryKeyOrder != null ) { + final ArrayList foreignKeyColumnsCopy = new ArrayList<>( columns ); + for ( int i = 0; i < foreignKeyColumnsCopy.size(); i++ ) { + columns.set( i, foreignKeyColumnsCopy.get( originalPrimaryKeyOrder[i] ) ); + } + } + } + } + } + } + } + for ( UserDefinedType userDefinedType : namespace.getUserDefinedTypes() ) { + if ( userDefinedType.getColumns().size() > 1 ) { + final List userDefinedTypeColumns = columnOrderingStrategy.orderUserDefinedTypeColumns( + userDefinedType, + this + ); + if ( userDefinedTypeColumns != null ) { + userDefinedType.reorderColumns( userDefinedTypeColumns ); + } + } + } + } + } + + private boolean shouldOrderTableColumns() { + final ConfigurationService configurationService = metadataBuildingOptions.getServiceRegistry() + .getService( ConfigurationService.class ); + final Set groupings = SchemaManagementToolCoordinator.ActionGrouping.interpret( + this, + configurationService.getSettings() + ); + if ( groupings.isEmpty() ) { + return false; + } + for ( SchemaManagementToolCoordinator.ActionGrouping grouping : groupings ) { + if ( isColumnOrderingRelevant( grouping.getScriptAction() ) || isColumnOrderingRelevant( grouping.getDatabaseAction() ) ) { + return true; + } + } + return false; + } + + private static boolean isColumnOrderingRelevant(Action grouping) { + switch ( grouping ) { + case CREATE: + case CREATE_DROP: + case CREATE_ONLY: + return true; + default: + return false; + } + } + @Override public void validate() throws MappingException { for ( PersistentClass entityBinding : this.getEntityBindings() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/relational/ColumnOrderingStrategy.java b/hibernate-core/src/main/java/org/hibernate/boot/model/relational/ColumnOrderingStrategy.java new file mode 100644 index 0000000000..795040d6c2 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/relational/ColumnOrderingStrategy.java @@ -0,0 +1,56 @@ +/* + * 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.boot.model.relational; + +import java.util.List; + +import org.hibernate.Incubating; +import org.hibernate.boot.Metadata; +import org.hibernate.dialect.temptable.TemporaryTableColumn; +import org.hibernate.mapping.Column; +import org.hibernate.mapping.Constraint; +import org.hibernate.mapping.Table; +import org.hibernate.mapping.UserDefinedType; + +/** + * A pluggable contract that allows ordering of columns within {@link org.hibernate.mapping.Table}, + * {@link org.hibernate.mapping.Constraint} and {@link org.hibernate.mapping.UserDefinedType}. + *

+ * Whenever reasonable, the use of a custom {@linkplain ColumnOrderingStrategy} is highly + * recommended in preference to tedious and repetitive explicit table and column name + * mappings. It's anticipated that most projects using Hibernate will feature a custom + * implementation of {@code ImplicitNamingStrategy}. + *

+ * An {@linkplain ColumnOrderingStrategy} may be selected using the configuration property + * {@value org.hibernate.cfg.AvailableSettings#COLUMN_ORDERING_STRATEGY}. + */ +@Incubating +public interface ColumnOrderingStrategy { + + /** + * Orders the columns of the table. + * May return null if columns were not ordered. + */ + List orderTableColumns(Table table, Metadata metadata); + + /** + * Orders the columns of the constraint. + * May return null if columns were not ordered. + */ + List orderConstraintColumns(Constraint constraint, Metadata metadata); + + /** + * Orders the columns of the user defined type. + * May return null if columns were not ordered. + */ + List orderUserDefinedTypeColumns(UserDefinedType userDefinedType, Metadata metadata); + + /** + * Orders the columns of the temporary table. + */ + void orderTemporaryTableColumns(List temporaryTableColumns, Metadata metadata); +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/relational/ColumnOrderingStrategyLegacy.java b/hibernate-core/src/main/java/org/hibernate/boot/model/relational/ColumnOrderingStrategyLegacy.java new file mode 100644 index 0000000000..5aa5b3bcc7 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/relational/ColumnOrderingStrategyLegacy.java @@ -0,0 +1,42 @@ +/* + * 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.boot.model.relational; + +import java.util.List; + +import org.hibernate.boot.Metadata; +import org.hibernate.dialect.temptable.TemporaryTableColumn; +import org.hibernate.mapping.Column; +import org.hibernate.mapping.Constraint; +import org.hibernate.mapping.Table; +import org.hibernate.mapping.UserDefinedType; + +/** + * A no-op implementation. + */ +public class ColumnOrderingStrategyLegacy implements ColumnOrderingStrategy { + public static final ColumnOrderingStrategyLegacy INSTANCE = new ColumnOrderingStrategyLegacy(); + + @Override + public List orderTableColumns(Table table, Metadata metadata) { + return null; + } + + @Override + public List orderConstraintColumns(Constraint constraint, Metadata metadata) { + return null; + } + + @Override + public List orderUserDefinedTypeColumns(UserDefinedType userDefinedType, Metadata metadata) { + return null; + } + + @Override + public void orderTemporaryTableColumns(List temporaryTableColumns, Metadata metadata) { + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/relational/ColumnOrderingStrategyStandard.java b/hibernate-core/src/main/java/org/hibernate/boot/model/relational/ColumnOrderingStrategyStandard.java new file mode 100644 index 0000000000..a2208f56c6 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/relational/ColumnOrderingStrategyStandard.java @@ -0,0 +1,213 @@ +/* + * 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.boot.model.relational; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; + +import org.hibernate.boot.Metadata; +import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.temptable.TemporaryTableColumn; +import org.hibernate.engine.jdbc.Size; +import org.hibernate.mapping.Column; +import org.hibernate.mapping.Constraint; +import org.hibernate.mapping.Table; +import org.hibernate.mapping.UserDefinedType; + +import static java.lang.Math.log; +import static org.hibernate.type.SqlTypes.*; + +/** + * Standard implementation that orders columns by size and name + * following roughly this ordering: order by max(physicalSizeBytes, 4), physicalSizeBytes > 2048, name + */ +public class ColumnOrderingStrategyStandard implements ColumnOrderingStrategy { + public static final ColumnOrderingStrategyStandard INSTANCE = new ColumnOrderingStrategyStandard(); + + //needed for converting precision from decimal to binary digits + private static final double DECIMAL_TO_BYTES_QUOTIENT = ( log( 10 ) / log( 2 ) ) * 8; + + @Override + public List orderTableColumns(Table table, Metadata metadata) { + return orderColumns( table.getColumns(), metadata ); + } + + @Override + public List orderUserDefinedTypeColumns(UserDefinedType userDefinedType, Metadata metadata) { + return orderColumns( userDefinedType.getColumns(), metadata ); + } + + @Override + public List orderConstraintColumns(Constraint constraint, Metadata metadata) { + return orderColumns( constraint.getColumns(), metadata ); + } + + @Override + public void orderTemporaryTableColumns(List temporaryTableColumns, Metadata metadata) { + temporaryTableColumns.sort( new TemporaryTableColumnComparator( metadata ) ); + } + + protected List orderColumns(Collection columns, Metadata metadata) { + final ArrayList orderedColumns = new ArrayList<>( columns ); + orderedColumns.sort( new ColumnComparator( metadata ) ); + return orderedColumns; + } + + protected static class ColumnComparator implements Comparator { + private final Metadata metadata; + + protected ColumnComparator(Metadata metadata) { + this.metadata = metadata; + } + + @Override + public int compare(Column o1, Column o2) { + final Dialect dialect = metadata.getDatabase().getDialect(); + final int physicalSizeInBytes1 = physicalSizeInBytes( + o1.getSqlTypeCode( metadata ), + o1.getColumnSize( dialect, metadata ), + metadata + ); + final int physicalSizeInBytes2 = physicalSizeInBytes( + o2.getSqlTypeCode( metadata ), + o2.getColumnSize( dialect, metadata ), + metadata + ); + int cmp = Integer.compare( Integer.max( physicalSizeInBytes1, 4 ), Integer.max( physicalSizeInBytes2, 4 ) ); + if ( cmp != 0 ) { + return cmp; + } + cmp = Boolean.compare( physicalSizeInBytes1 > 2048, physicalSizeInBytes2 > 2048 ); + if ( cmp != 0 ) { + return cmp; + } + return o1.getName().compareTo( o2.getName() ); + } + } + + protected static class TemporaryTableColumnComparator implements Comparator { + private final Metadata metadata; + + protected TemporaryTableColumnComparator(Metadata metadata) { + this.metadata = metadata; + } + + @Override + public int compare(TemporaryTableColumn o1, TemporaryTableColumn o2) { + final int physicalSizeInBytes1 = physicalSizeInBytes( + o1.getJdbcMapping().getJdbcType().getDefaultSqlTypeCode(), + o1.getSize(), + metadata + ); + final int physicalSizeInBytes2 = physicalSizeInBytes( + o2.getJdbcMapping().getJdbcType().getDefaultSqlTypeCode(), + o2.getSize(), + metadata + ); + int cmp = Integer.compare( Integer.max( physicalSizeInBytes1, 4 ), Integer.max( physicalSizeInBytes2, 4 ) ); + if ( cmp != 0 ) { + return cmp; + } + cmp = Boolean.compare( physicalSizeInBytes1 > 2048, physicalSizeInBytes2 > 2048 ); + if ( cmp != 0 ) { + return cmp; + } + return o1.getColumnName().compareTo( o2.getColumnName() ); + } + } + + protected static int physicalSizeInBytes(int sqlTypeCode, Size columnSize, Metadata metadata) { + long length; + int precision; + switch ( sqlTypeCode ) { + case BOOLEAN: + case TINYINT: + case BIT: + return 1; + case SMALLINT: + return 2; + case FLOAT: + if ( columnSize.getPrecision() != null ) { + return (int) Math.ceil( columnSize.getPrecision() / DECIMAL_TO_BYTES_QUOTIENT ); + } + case REAL: + case INTEGER: + return 4; + case BIGINT: + case DOUBLE: + return 8; + case NUMERIC: + case DECIMAL: + if ( columnSize.getPrecision() == null ) { + precision = metadata.getDatabase().getDialect().getDefaultDecimalPrecision(); + } + else { + precision = columnSize.getPrecision(); + } + return (int) Math.ceil( precision / DECIMAL_TO_BYTES_QUOTIENT ); + case CHAR: + case NCHAR: + case VARCHAR: + case NVARCHAR: + case LONGVARCHAR: + case LONG32VARCHAR: + if ( columnSize.getLength() == null ) { + length = Size.DEFAULT_LENGTH; + } + else { + length = columnSize.getLength(); + } + if ( length == Size.DEFAULT_LENGTH ) { + return metadata.getDatabase().getDialect().getMaxVarcharLength(); + } + return (int) length; + case LONGNVARCHAR: + case LONG32NVARCHAR: + if ( columnSize.getLength() == null ) { + length = Size.DEFAULT_LENGTH; + } + else { + length = columnSize.getLength(); + } + if ( length == Size.DEFAULT_LENGTH ) { + return metadata.getDatabase().getDialect().getMaxNVarcharLength(); + } + return (int) length; + case BINARY: + case VARBINARY: + case LONGVARBINARY: + case LONG32VARBINARY: + if ( columnSize.getLength() == null ) { + length = Size.DEFAULT_LENGTH; + } + else { + length = columnSize.getLength(); + } + if ( length == Size.DEFAULT_LENGTH ) { + return metadata.getDatabase().getDialect().getMaxVarbinaryLength(); + } + return (int) length; + case DATE: + case TIME: + case TIME_WITH_TIMEZONE: + return 4; + case TIMESTAMP: + case TIMESTAMP_UTC: + case TIMESTAMP_WITH_TIMEZONE: + case INTERVAL_SECOND: + return 8; + case UUID: + return 16; + case INET: + return 19; + default: + return Integer.MAX_VALUE; + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java index 352038c251..90cc50dac8 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorBuilder.java @@ -14,6 +14,9 @@ import org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl; import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl; import org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl; import org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl; +import org.hibernate.boot.model.relational.ColumnOrderingStrategy; +import org.hibernate.boot.model.relational.ColumnOrderingStrategyLegacy; +import org.hibernate.boot.model.relational.ColumnOrderingStrategyStandard; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.selector.SimpleStrategyRegistrationImpl; import org.hibernate.boot.registry.selector.StrategyRegistration; @@ -114,6 +117,7 @@ public class StrategySelectorBuilder { addTransactionCoordinatorBuilders( strategySelector ); addSqmMultiTableMutationStrategies( strategySelector ); addImplicitNamingStrategies( strategySelector ); + addColumnOrderingStrategies( strategySelector ); addCacheKeysFactories( strategySelector ); addJsonFormatMappers( strategySelector ); addXmlFormatMappers( strategySelector ); @@ -243,6 +247,19 @@ public class StrategySelectorBuilder { ); } + private static void addColumnOrderingStrategies(StrategySelectorImpl strategySelector) { + strategySelector.registerStrategyImplementor( + ColumnOrderingStrategy.class, + "default", + ColumnOrderingStrategyStandard.class + ); + strategySelector.registerStrategyImplementor( + ColumnOrderingStrategy.class, + "legacy", + ColumnOrderingStrategyLegacy.class + ); + } + private static void addCacheKeysFactories(StrategySelectorImpl strategySelector) { strategySelector.registerStrategyImplementor( CacheKeysFactory.class, diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadata.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadata.java index 077a608fe9..f236ae87cc 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadata.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadata.java @@ -213,6 +213,11 @@ public abstract class AbstractDelegatingMetadata implements MetadataImplementor return delegate.getTypeConfiguration(); } + @Override + public void orderColumns(boolean forceOrdering) { + delegate.orderColumns( false ); + } + @Override public void validate() throws MappingException { delegate.validate(); diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadataBuilderImplementor.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadataBuilderImplementor.java index fdca1c10c2..d2437e179c 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadataBuilderImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingMetadataBuilderImplementor.java @@ -22,6 +22,7 @@ import org.hibernate.boot.model.convert.spi.ConverterDescriptor; import org.hibernate.boot.model.naming.ImplicitNamingStrategy; import org.hibernate.boot.model.naming.PhysicalNamingStrategy; import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject; +import org.hibernate.boot.model.relational.ColumnOrderingStrategy; import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cfg.MetadataSourceType; import org.hibernate.query.sqm.function.SqmFunctionDescriptor; @@ -82,6 +83,12 @@ public abstract class AbstractDelegatingMetadataBuilderImplementor getMappedSuperclassMappingsCopy(); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AggregateComponentSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/AggregateComponentSecondPass.java index 0f7761e7cf..9a67fc005f 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AggregateComponentSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AggregateComponentSecondPass.java @@ -7,6 +7,7 @@ package org.hibernate.cfg; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.TreeSet; @@ -22,6 +23,7 @@ import org.hibernate.boot.spi.InFlightMetadataCollector; import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.aggregate.AggregateSupport; +import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.StringHelper; import org.hibernate.mapping.AggregateColumn; import org.hibernate.mapping.BasicValue; @@ -88,16 +90,18 @@ public class AggregateComponentSecondPass implements SecondPass { udt.setComment( comment.value() ); } for ( org.hibernate.mapping.Column aggregatedColumn : aggregatedColumns ) { - // Clone the column, since the column name will be changed later on, - // but we don't want the DDL to be affected by that udt.addColumn( aggregatedColumn ); } final UserDefinedType registeredUdt = defaultNamespace.createUserDefinedType( udtName, name -> udt ); - addAuxiliaryObjects = registeredUdt == udt; - if ( registeredUdt != udt ) { + if ( registeredUdt == udt ) { + addAuxiliaryObjects = true; + orderColumns( registeredUdt ); + } + else { + addAuxiliaryObjects = false; validateEqual( registeredUdt, udt ); } } @@ -181,6 +185,67 @@ public class AggregateComponentSecondPass implements SecondPass { propertyHolder.getTable().getColumns().removeAll( aggregatedColumns ); } + private void orderColumns(UserDefinedType userDefinedType) { + final Class componentClass = component.getComponentClass(); + final int[] originalOrder = component.sortProperties(); + final int[] propertyMappingIndex; + if ( ReflectHelper.isRecord( componentClass ) ) { + if ( originalOrder == null ) { + propertyMappingIndex = null; + } + else { + final String[] componentNames = ReflectHelper.getRecordComponentNames( componentClass ); + propertyMappingIndex = determinePropertyMappingIndex( componentNames ); + } + } + else { + // At some point we could do some byte code analysis to determine the order based on a constructor + return; + } + final ArrayList orderedColumns = new ArrayList<>( userDefinedType.getColumnSpan() ); + final List properties = component.getProperties(); + if ( propertyMappingIndex == null ) { + for ( Property property : properties ) { + addColumns( orderedColumns, property.getValue() ); + } + } + else { + for ( int newIndex = 0; newIndex < propertyMappingIndex.length; newIndex++ ) { + final int propertyIndex = propertyMappingIndex[newIndex]; + addColumns( orderedColumns, properties.get( propertyIndex ).getValue() ); + } + } + userDefinedType.reorderColumns( orderedColumns ); + } + + private static void addColumns(ArrayList orderedColumns, Value value) { + if ( value instanceof Component ) { + final Component subComponent = (Component) value; + if ( subComponent.getAggregateColumn() == null ) { + for ( Property property : subComponent.getProperties() ) { + addColumns( orderedColumns, property.getValue() ); + } + } + else { + orderedColumns.add( subComponent.getAggregateColumn() ); + } + } + else { + orderedColumns.addAll( value.getColumns() ); + } + } + + private static int[] determinePropertyMappingIndex(String[] componentNames) { + final String[] sortedComponentNames = componentNames.clone(); + final int[] index = new int[componentNames.length]; + Arrays.sort( sortedComponentNames ); + for ( int i = 0; i < componentNames.length; i++ ) { + final int newIndex = Arrays.binarySearch( sortedComponentNames, componentNames[i] ); + index[newIndex] = i; + } + return index; + } + private void validateSupportedColumnTypes(String basePath, Component component) { for ( Property property : component.getProperties() ) { final Value value = property.getValue(); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java index 1599f392ca..37151999e6 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java @@ -851,6 +851,25 @@ public interface AvailableSettings { @Incubating String ID_DB_STRUCTURE_NAMING_STRATEGY = "hibernate.id.db_structure_naming_strategy"; + /** + * Used to specify the {@link org.hibernate.boot.model.relational.ColumnOrderingStrategy} + * class to use. The following shortcut names are defined for this setting: + *

+ * By default, the {@linkplain org.hibernate.boot.model.relational.ColumnOrderingStrategy} registered under the key + * {@code "default"} is used. If no strategy is explicitly registered under that key, + * {@link org.hibernate.boot.model.relational.ColumnOrderingStrategyStandard} is used. + * + * @see org.hibernate.boot.MetadataBuilder#applyColumnOrderingStrategy + * + * @since 6.2 + */ + String COLUMN_ORDERING_STRATEGY = "hibernate.column_ordering_strategy"; + /** * Specifies the order in which metadata sources should be processed, is a delimited list * of values defined by {@link MetadataSourceType}. diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DB2StructJdbcType.java b/hibernate-core/src/main/java/org/hibernate/dialect/DB2StructJdbcType.java index e216927d39..b695ef42cd 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DB2StructJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DB2StructJdbcType.java @@ -13,6 +13,7 @@ import java.sql.SQLException; import java.sql.SQLXML; import org.hibernate.metamodel.mapping.EmbeddableMappingType; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.SqlTypes; import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueExtractor; @@ -50,9 +51,9 @@ public class DB2StructJdbcType implements AggregateJdbcType { this( null, null ); } - public DB2StructJdbcType(String structTypeName, EmbeddableMappingType embeddableMappingType) { - this.structTypeName = structTypeName; + public DB2StructJdbcType(EmbeddableMappingType embeddableMappingType, String structTypeName) { this.embeddableMappingType = embeddableMappingType; + this.structTypeName = structTypeName; // We cache the extractor for Object[] here // since that is used in AggregateEmbeddableFetchImpl and AggregateEmbeddableResultImpl this.objectArrayExtractor = createBasicExtractor( new UnknownBasicJavaType<>( Object[].class ) ); @@ -69,8 +70,11 @@ public class DB2StructJdbcType implements AggregateJdbcType { } @Override - public AggregateJdbcType resolveAggregateJdbcType(EmbeddableMappingType mappingType, String sqlType) { - return new DB2StructJdbcType( sqlType, mappingType ); + public AggregateJdbcType resolveAggregateJdbcType( + EmbeddableMappingType mappingType, + String sqlType, + RuntimeModelCreationContext creationContext) { + return new DB2StructJdbcType( mappingType, sqlType ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleJsonJdbcType.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleJsonJdbcType.java index efa35eb1ee..1f3edc9abb 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleJsonJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleJsonJdbcType.java @@ -7,6 +7,7 @@ package org.hibernate.dialect; import org.hibernate.metamodel.mapping.EmbeddableMappingType; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.jdbc.AggregateJdbcType; import org.hibernate.type.descriptor.jdbc.OracleJsonBlobJdbcType; @@ -32,7 +33,10 @@ public class OracleJsonJdbcType extends OracleJsonBlobJdbcType { } @Override - public AggregateJdbcType resolveAggregateJdbcType(EmbeddableMappingType mappingType, String sqlType) { + public AggregateJdbcType resolveAggregateJdbcType( + EmbeddableMappingType mappingType, + String sqlType, + RuntimeModelCreationContext creationContext) { return new OracleJsonJdbcType( mappingType ); } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleStructJdbcType.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleStructJdbcType.java index d60bc68061..a77cb3ac16 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleStructJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleStructJdbcType.java @@ -16,10 +16,12 @@ import java.sql.Struct; import java.util.Locale; import org.hibernate.HibernateException; +import org.hibernate.boot.model.naming.Identifier; import org.hibernate.metamodel.mapping.AttributeMapping; import org.hibernate.metamodel.mapping.EmbeddableMappingType; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.MappingType; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.SqlTypes; import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueExtractor; @@ -54,17 +56,19 @@ public class OracleStructJdbcType implements AggregateJdbcType { }; private final String oracleTypeName; + private final int[] orderMapping; private final EmbeddableMappingType embeddableMappingType; private final ValueExtractor objectArrayExtractor; private OracleStructJdbcType() { // The default instance is for reading only and will return an Object[] - this( null, null ); + this( null, null, null ); } - public OracleStructJdbcType(EmbeddableMappingType embeddableMappingType, String typeName) { - this.oracleTypeName = typeName == null ? null : typeName.toUpperCase( Locale.ROOT ); + public OracleStructJdbcType(EmbeddableMappingType embeddableMappingType, String typeName, int[] orderMapping) { this.embeddableMappingType = embeddableMappingType; + this.oracleTypeName = typeName == null ? null : typeName.toUpperCase( Locale.ROOT ); + this.orderMapping = orderMapping; // We cache the extractor for Object[] here // since that is used in AggregateEmbeddableFetchImpl and AggregateEmbeddableResultImpl this.objectArrayExtractor = createBasicExtractor( new UnknownBasicJavaType<>( Object[].class ) ); @@ -76,8 +80,19 @@ public class OracleStructJdbcType implements AggregateJdbcType { } @Override - public AggregateJdbcType resolveAggregateJdbcType(EmbeddableMappingType mappingType, String sqlType) { - return new OracleStructJdbcType( mappingType, sqlType ); + public AggregateJdbcType resolveAggregateJdbcType( + EmbeddableMappingType mappingType, + String sqlType, + RuntimeModelCreationContext creationContext) { + return new OracleStructJdbcType( + mappingType, + sqlType, + creationContext.getBootModel() + .getDatabase() + .getDefaultNamespace() + .locateUserDefinedType( Identifier.toIdentifier( sqlType ) ) + .getOrderMapping() + ); } @Override @@ -126,7 +141,7 @@ public class OracleStructJdbcType implements AggregateJdbcType { @Override public Object[] extractJdbcValues(Object rawJdbcValue, WrapperOptions options) throws SQLException { final Object[] attributes = ( (Struct) rawJdbcValue ).getAttributes(); - wrapRawJdbcValues( embeddableMappingType, attributes, 0, options ); + wrapRawJdbcValues( embeddableMappingType, orderMapping, attributes, 0, options ); return attributes; } @@ -182,13 +197,14 @@ public class OracleStructJdbcType implements AggregateJdbcType { final Object[] values = struct.getAttributes(); final boolean jdbcRepresentation = getJavaType().getJavaTypeClass() == Object[].class; if ( jdbcRepresentation ) { - wrapRawJdbcValues( embeddableMappingType, values, 0, options ); + wrapRawJdbcValues( embeddableMappingType, orderMapping, values, 0, options ); //noinspection unchecked return (X) values; } assert embeddableMappingType != null && embeddableMappingType.getJavaType() == getJavaType(); final Object[] attributeValues = getAttributeValues( embeddableMappingType, + orderMapping, values, options ); @@ -203,6 +219,7 @@ public class OracleStructJdbcType implements AggregateJdbcType { public static Object[] getAttributeValues( EmbeddableMappingType embeddableMappingType, + int[] orderMapping, Object[] rawJdbcValues, WrapperOptions options) throws SQLException { final int numberOfAttributeMappings = embeddableMappingType.getNumberOfAttributeMappings(); @@ -216,13 +233,22 @@ public class OracleStructJdbcType implements AggregateJdbcType { int jdbcIndex = 0; for ( int i = 0; i < numberOfAttributeMappings; i++ ) { final AttributeMapping attributeMapping = embeddableMappingType.getAttributeMapping( i ); - jdbcIndex += injectAttributeValue( attributeMapping, attributeValues, i, rawJdbcValues, jdbcIndex, options ); + jdbcIndex += injectAttributeValue( + attributeMapping, + orderMapping, + attributeValues, + i, + rawJdbcValues, + jdbcIndex, + options + ); } return attributeValues; } private static int injectAttributeValue( AttributeMapping attributeMapping, + int[] orderMapping, Object[] attributeValues, int attributeIndex, Object[] rawJdbcValues, @@ -230,17 +256,36 @@ public class OracleStructJdbcType implements AggregateJdbcType { WrapperOptions options) throws SQLException { final MappingType mappedType = attributeMapping.getMappedType(); final int jdbcValueCount; - final Object rawJdbcValue = rawJdbcValues[jdbcIndex]; + final Object rawJdbcValue; + if ( orderMapping == null ) { + rawJdbcValue = rawJdbcValues[jdbcIndex]; + } + else { + rawJdbcValue = rawJdbcValues[orderMapping[jdbcIndex]]; + } if ( mappedType instanceof EmbeddableMappingType ) { final EmbeddableMappingType embeddableMappingType = (EmbeddableMappingType) mappedType; if ( embeddableMappingType.getAggregateMapping() != null ) { jdbcValueCount = 1; - if ( rawJdbcValue instanceof Struct ) { - final Object[] subValues = getAttributeValues( - embeddableMappingType, - ( (Struct) rawJdbcValue ).getAttributes(), - options - ); + if ( rawJdbcValue == null ) { + attributeValues[attributeIndex] = null; + } + else { + final AggregateJdbcType aggregateJdbcType = (AggregateJdbcType) embeddableMappingType.getAggregateMapping() + .getJdbcMapping() + .getJdbcType(); + final Object[] subValues; + if ( aggregateJdbcType instanceof OracleStructJdbcType ) { + subValues = getAttributeValues( + embeddableMappingType, + ( (OracleStructJdbcType) aggregateJdbcType ).orderMapping, + ( (Struct) rawJdbcValue ).getAttributes(), + options + ); + } + else { + subValues = aggregateJdbcType.extractJdbcValues( rawJdbcValue, options ); + } attributeValues[attributeIndex] = embeddableMappingType.getRepresentationStrategy() .getInstantiator() .instantiate( @@ -250,15 +295,12 @@ public class OracleStructJdbcType implements AggregateJdbcType { .getFactory() ); } - else { - attributeValues[attributeIndex] = rawJdbcValue; - } } else { jdbcValueCount = embeddableMappingType.getJdbcValueCount(); final Object[] jdbcValues = new Object[jdbcValueCount]; System.arraycopy( rawJdbcValues, jdbcIndex, jdbcValues, 0, jdbcValues.length ); - final Object[] subValues = getAttributeValues( embeddableMappingType, jdbcValues, options ); + final Object[] subValues = getAttributeValues( embeddableMappingType, orderMapping, jdbcValues, options ); attributeValues[attributeIndex] = embeddableMappingType.getRepresentationStrategy() .getInstantiator() .instantiate( @@ -297,6 +339,7 @@ public class OracleStructJdbcType implements AggregateJdbcType { private static int wrapRawJdbcValues( EmbeddableMappingType embeddableMappingType, + int[] orderMapping, Object[] jdbcValues, int jdbcIndex, WrapperOptions options) throws SQLException { @@ -311,16 +354,29 @@ public class OracleStructJdbcType implements AggregateJdbcType { final AggregateJdbcType aggregateJdbcType = (AggregateJdbcType) embeddableType.getAggregateMapping() .getJdbcMapping() .getJdbcType(); - jdbcValues[jdbcIndex] = aggregateJdbcType.extractJdbcValues( jdbcValues[jdbcIndex], options ); + final Object rawJdbcValue; + if ( orderMapping == null ) { + rawJdbcValue = jdbcValues[jdbcIndex]; + } + else { + rawJdbcValue = jdbcValues[orderMapping[jdbcIndex]]; + } + jdbcValues[jdbcIndex] = aggregateJdbcType.extractJdbcValues( rawJdbcValue, options ); jdbcIndex++; } else { - jdbcIndex = wrapRawJdbcValues( embeddableType, jdbcValues, jdbcIndex, options ); + jdbcIndex = wrapRawJdbcValues( embeddableType, orderMapping, jdbcValues, jdbcIndex, options ); } } else { assert attributeMapping.getJdbcTypeCount() == 1; - final Object rawJdbcValue = jdbcValues[jdbcIndex]; + final Object rawJdbcValue; + if ( orderMapping == null ) { + rawJdbcValue = jdbcValues[jdbcIndex]; + } + else { + rawJdbcValue = jdbcValues[orderMapping[jdbcIndex]]; + } if ( rawJdbcValue != null ) { final JdbcMapping jdbcMapping = attributeMapping.getJdbcMappings().get( 0 ); switch ( jdbcMapping.getJdbcType().getDefaultSqlTypeCode() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleXmlJdbcType.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleXmlJdbcType.java index 93b6108478..d05b87006b 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleXmlJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleXmlJdbcType.java @@ -12,6 +12,7 @@ import java.sql.SQLException; import java.sql.Types; import org.hibernate.metamodel.mapping.EmbeddableMappingType; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.java.JavaType; @@ -30,7 +31,10 @@ public class OracleXmlJdbcType extends XmlJdbcType { } @Override - public AggregateJdbcType resolveAggregateJdbcType(EmbeddableMappingType mappingType, String sqlType) { + public AggregateJdbcType resolveAggregateJdbcType( + EmbeddableMappingType mappingType, + String sqlType, + RuntimeModelCreationContext creationContext) { return new OracleXmlJdbcType( mappingType ); } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLJsonJdbcType.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLJsonJdbcType.java index a632eb0dad..5f1b9fcdca 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLJsonJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLJsonJdbcType.java @@ -7,6 +7,7 @@ package org.hibernate.dialect; import org.hibernate.metamodel.mapping.EmbeddableMappingType; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.descriptor.jdbc.AggregateJdbcType; /** @@ -21,7 +22,10 @@ public class PostgreSQLJsonJdbcType extends AbstractPostgreSQLJsonJdbcType { } @Override - public AggregateJdbcType resolveAggregateJdbcType(EmbeddableMappingType mappingType, String sqlType) { + public AggregateJdbcType resolveAggregateJdbcType( + EmbeddableMappingType mappingType, + String sqlType, + RuntimeModelCreationContext creationContext) { return new PostgreSQLJsonJdbcType( mappingType ); } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLJsonbJdbcType.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLJsonbJdbcType.java index cb6d0ac47a..5afa3446d0 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLJsonbJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLJsonbJdbcType.java @@ -7,6 +7,7 @@ package org.hibernate.dialect; import org.hibernate.metamodel.mapping.EmbeddableMappingType; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.descriptor.jdbc.AggregateJdbcType; /** @@ -21,7 +22,10 @@ public class PostgreSQLJsonbJdbcType extends AbstractPostgreSQLJsonJdbcType { } @Override - public AggregateJdbcType resolveAggregateJdbcType(EmbeddableMappingType mappingType, String sqlType) { + public AggregateJdbcType resolveAggregateJdbcType( + EmbeddableMappingType mappingType, + String sqlType, + RuntimeModelCreationContext creationContext) { return new PostgreSQLJsonbJdbcType( mappingType ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLStructJdbcType.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLStructJdbcType.java index e4c321dd74..bd6770999b 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLStructJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLStructJdbcType.java @@ -20,6 +20,7 @@ import java.time.temporal.TemporalAccessor; import java.util.ArrayList; import java.util.TimeZone; +import org.hibernate.boot.model.naming.Identifier; import org.hibernate.internal.util.CharSequenceHelper; import org.hibernate.metamodel.mapping.AttributeMapping; import org.hibernate.metamodel.mapping.BasicValuedMapping; @@ -27,6 +28,7 @@ import org.hibernate.metamodel.mapping.EmbeddableMappingType; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.SelectableMapping; import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.spi.StringBuilderSqlAppender; import org.hibernate.type.SqlTypes; @@ -81,17 +83,19 @@ public class PostgreSQLStructJdbcType extends PostgreSQLPGObjectJdbcType impleme .toFormatter(); } + private final int[] orderMapping; private final EmbeddableMappingType embeddableMappingType; private final ValueExtractor objectArrayExtractor; private PostgreSQLStructJdbcType() { // The default instance is for reading only and will return an Object[] - this( null, null ); + this( null, null, null ); } - public PostgreSQLStructJdbcType(EmbeddableMappingType embeddableMappingType, String typeName) { + public PostgreSQLStructJdbcType(EmbeddableMappingType embeddableMappingType, String typeName, int[] orderMapping) { super( typeName, SqlTypes.STRUCT ); this.embeddableMappingType = embeddableMappingType; + this.orderMapping = orderMapping; // We cache the extractor for Object[] here // since that is used in AggregateEmbeddableFetchImpl and AggregateEmbeddableResultImpl this.objectArrayExtractor = super.getExtractor( new UnknownBasicJavaType<>( Object[].class ) ); @@ -103,8 +107,19 @@ public class PostgreSQLStructJdbcType extends PostgreSQLPGObjectJdbcType impleme } @Override - public AggregateJdbcType resolveAggregateJdbcType(EmbeddableMappingType mappingType, String sqlType) { - return new PostgreSQLStructJdbcType( mappingType, sqlType ); + public AggregateJdbcType resolveAggregateJdbcType( + EmbeddableMappingType mappingType, + String sqlType, + RuntimeModelCreationContext creationContext) { + return new PostgreSQLStructJdbcType( + mappingType, + sqlType, + creationContext.getBootModel() + .getDatabase() + .getDefaultNamespace() + .locateUserDefinedType( Identifier.toIdentifier( sqlType ) ) + .getOrderMapping() + ); } @Override @@ -267,7 +282,7 @@ public class PostgreSQLStructJdbcType extends PostgreSQLPGObjectJdbcType impleme continue; } assert repeatsChar( string, i, 1 << quoteLevel, '"' ); - final JdbcMapping jdbcMapping = embeddableMappingType.getJdbcValueSelectable( column ) + final JdbcMapping jdbcMapping = getJdbcValueSelectable( column ) .getJdbcMapping(); switch ( jdbcMapping.getJdbcType().getDefaultSqlTypeCode() ) { case SqlTypes.DATE: @@ -381,7 +396,7 @@ public class PostgreSQLStructJdbcType extends PostgreSQLPGObjectJdbcType impleme i += expectedQuotes - 1; if ( string.charAt( i + 1 ) == '(' ) { // This could be a nested struct - final JdbcMapping jdbcMapping = embeddableMappingType.getJdbcValueSelectable( column ) + final JdbcMapping jdbcMapping = getJdbcValueSelectable( column ) .getJdbcMapping(); if ( jdbcMapping.getJdbcType() instanceof PostgreSQLStructJdbcType ) { final PostgreSQLStructJdbcType structJdbcType; @@ -438,7 +453,7 @@ public class PostgreSQLStructJdbcType extends PostgreSQLPGObjectJdbcType impleme values[column] = null; } else { - final JdbcMapping jdbcMapping = embeddableMappingType.getJdbcValueSelectable( column ).getJdbcMapping(); + final JdbcMapping jdbcMapping = getJdbcValueSelectable( column ).getJdbcMapping(); if ( jdbcMapping.getJdbcType().getDefaultSqlTypeCode() == SqlTypes.BOOLEAN ) { values[column] = fromRawObject( jdbcMapping, @@ -467,7 +482,6 @@ public class PostgreSQLStructJdbcType extends PostgreSQLPGObjectJdbcType impleme } else { values[column] = fromString( - embeddableMappingType, column, string, start, @@ -484,6 +498,13 @@ public class PostgreSQLStructJdbcType extends PostgreSQLPGObjectJdbcType impleme throw new IllegalArgumentException( "Struct not properly formed: " + string.substring( start ) ); } + private SelectableMapping getJdbcValueSelectable(int jdbcValueSelectableIndex) { + if ( orderMapping != null ) { + jdbcValueSelectableIndex = orderMapping[jdbcValueSelectableIndex]; + } + return embeddableMappingType.getJdbcValueSelectable( jdbcValueSelectableIndex ); + } + private static boolean repeatsChar(String string, int start, int times, char c) { final int end = start + times; if ( end < string.length() ) { @@ -497,14 +518,13 @@ public class PostgreSQLStructJdbcType extends PostgreSQLPGObjectJdbcType impleme return false; } - private static Object fromString( - EmbeddableMappingType embeddableMappingType, + private Object fromString( int selectableIndex, String string, int start, int end) { return fromString( - embeddableMappingType.getJdbcValueSelectable( selectableIndex ).getJdbcMapping(), + getJdbcValueSelectable( selectableIndex ).getJdbcMapping(), string, start, end diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgresPlusDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgresPlusDialect.java index f3145f1d36..1e49fd6f4c 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgresPlusDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgresPlusDialect.java @@ -15,8 +15,6 @@ import jakarta.persistence.TemporalType; import org.hibernate.dialect.function.CommonFunctionFactory; import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo; -import org.hibernate.procedure.internal.PostgreSQLCallableStatementSupport; -import org.hibernate.procedure.spi.CallableStatementSupport; import org.hibernate.query.sqm.CastType; import org.hibernate.query.sqm.TemporalUnit; import org.hibernate.query.spi.QueryEngine; @@ -109,11 +107,6 @@ public class PostgresPlusDialect extends PostgreSQLDialect { return (ResultSet) ps.getObject( 1 ); } - @Override - public CallableStatementSupport getCallableStatementSupport() { - return getVersion().isSameOrAfter( 10 ) ? PostgreSQLCallableStatementSupport.INSTANCE : PostgreSQLCallableStatementSupport.V10_INSTANCE; - } - @Override public String getSelectGUIDString() { return "select uuid_generate_v1"; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/temptable/StandardTemporaryTableExporter.java b/hibernate-core/src/main/java/org/hibernate/dialect/temptable/StandardTemporaryTableExporter.java index 790024e410..54b520c2ed 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/temptable/StandardTemporaryTableExporter.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/temptable/StandardTemporaryTableExporter.java @@ -43,7 +43,7 @@ public class StandardTemporaryTableExporter implements TemporaryTableExporter { buffer.append( temporaryTable.getQualifiedTableName() ); buffer.append( '(' ); - for ( TemporaryTableColumn column : temporaryTable.getColumns() ) { + for ( TemporaryTableColumn column : temporaryTable.getColumnsForExport() ) { buffer.append( column.getColumnName() ).append( ' ' ); final int sqlTypeCode = column.getJdbcMapping().getJdbcType().getDefaultSqlTypeCode(); final String databaseTypeName = column.getSqlTypeDefinition(); @@ -68,7 +68,7 @@ public class StandardTemporaryTableExporter implements TemporaryTableExporter { } if ( dialect.supportsTemporaryTablePrimaryKey() ) { buffer.append( "primary key (" ); - for ( TemporaryTableColumn column : temporaryTable.getColumns() ) { + for ( TemporaryTableColumn column : temporaryTable.getColumnsForExport() ) { if ( column.isPrimaryKey() ) { buffer.append( column.getColumnName() ); buffer.append( ", " ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTable.java b/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTable.java index 4713f4d0c5..3149d6db57 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTable.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTable.java @@ -16,8 +16,8 @@ import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.relational.Exportable; import org.hibernate.boot.model.relational.QualifiedNameParser; import org.hibernate.boot.model.relational.QualifiedTableName; -import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.dialect.Dialect; +import org.hibernate.engine.jdbc.Size; import org.hibernate.id.OptimizableGenerator; import org.hibernate.id.enhanced.Optimizer; import org.hibernate.internal.CoreLogging; @@ -63,6 +63,7 @@ public class TemporaryTable implements Exportable, Contributable { private final TemporaryTableSessionUidColumn sessionUidColumn; private final List columns; + private final List columnsForExport; private final Dialect dialect; @@ -70,7 +71,7 @@ public class TemporaryTable implements Exportable, Contributable { EntityMappingType entityDescriptor, Function temporaryTableNameAdjuster, Dialect dialect, - SqlStringGenerationContext sqlStringGenerationContext, + RuntimeModelCreationContext creationContext, Function> columnInitializer) { this.entityDescriptor = entityDescriptor; final EntityPersister entityPersister = entityDescriptor.getEntityPersister(); @@ -104,7 +105,7 @@ public class TemporaryTable implements Exportable, Contributable { else { tableNameIdentifier = new Identifier( temporaryTableName, nameParts.getObjectName().isQuoted() ); } - this.qualifiedTableName = sqlStringGenerationContext.format( + this.qualifiedTableName = creationContext.getSessionFactory().getSqlStringGenerationContext().format( new QualifiedTableName( adjustedNameParts.getCatalogName() != null ? adjustedNameParts.getCatalogName() @@ -123,19 +124,21 @@ public class TemporaryTable implements Exportable, Contributable { final BasicType uuidType = typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.UUID_CHAR ); + final Size size = dialect.getSizeStrategy().resolveSize( + uuidType.getJdbcType(), + uuidType.getJavaTypeDescriptor(), + null, + null, + null + ); this.sessionUidColumn = new TemporaryTableSessionUidColumn( this, uuidType, typeConfiguration.getDdlTypeRegistry().getTypeName( uuidType.getJdbcType().getDefaultSqlTypeCode(), - dialect.getSizeStrategy().resolveSize( - uuidType.getJdbcType(), - uuidType.getJavaTypeDescriptor(), - null, - null, - null - ) - ) + size + ), + size ); } else { @@ -146,6 +149,16 @@ public class TemporaryTable implements Exportable, Contributable { columns.add( sessionUidColumn ); } this.columns = columns; + + if ( columns.size() > 1 ) { + final ArrayList columnsForExport = new ArrayList<>( columns ); + creationContext.getBootModel().getMetadataBuildingOptions().getColumnOrderingStrategy() + .orderTemporaryTableColumns( columnsForExport, creationContext.getMetadata() ); + this.columnsForExport = columnsForExport; + } + else { + this.columnsForExport = columns; + } } public static TemporaryTable createIdTable( @@ -157,7 +170,7 @@ public class TemporaryTable implements Exportable, Contributable { entityDescriptor, temporaryTableNameAdjuster, dialect, - runtimeModelCreationContext.getSessionFactory().getSqlStringGenerationContext(), + runtimeModelCreationContext, temporaryTable -> { final List columns = new ArrayList<>(); final PersistentClass entityBinding = runtimeModelCreationContext.getBootModel() @@ -178,6 +191,10 @@ public class TemporaryTable implements Exportable, Contributable { dialect, runtimeModelCreationContext.getMetadata() ), + column.getColumnSize( + dialect, + runtimeModelCreationContext.getMetadata() + ), column.isNullable(), true ) @@ -192,7 +209,7 @@ public class TemporaryTable implements Exportable, Contributable { if ( pluralAttribute.getSeparateCollectionTable() != null ) { // Ensure that the FK target columns are available ForeignKeyDescriptor keyDescriptor = pluralAttribute.getKeyDescriptor(); - if ( keyDescriptor==null ) { + if ( keyDescriptor == null ) { // This is expected to happen when processing a // PostInitCallbackEntry because the callbacks // are not ordered. The exception is caught in @@ -214,13 +231,17 @@ public class TemporaryTable implements Exportable, Contributable { columns.add( new TemporaryTableColumn( temporaryTable, - selectable.getText( dialect ), + column.getText( dialect ), selection.getJdbcMapping(), column.getSqlType( runtimeModelCreationContext.getTypeConfiguration(), dialect, runtimeModelCreationContext.getMetadata() ), + column.getColumnSize( + dialect, + runtimeModelCreationContext.getMetadata() + ), column.isNullable() ) ); @@ -246,7 +267,7 @@ public class TemporaryTable implements Exportable, Contributable { entityDescriptor, temporaryTableNameAdjuster, dialect, - runtimeModelCreationContext.getSessionFactory().getSqlStringGenerationContext(), + runtimeModelCreationContext, temporaryTable -> { final List columns = new ArrayList<>(); final PersistentClass entityBinding = runtimeModelCreationContext.getBootModel() @@ -273,8 +294,12 @@ public class TemporaryTable implements Exportable, Contributable { runtimeModelCreationContext.getMetadata() ) + " " + dialect.getIdentityColumnSupport().getIdentityColumnString( column.getSqlTypeCode( runtimeModelCreationContext.getMetadata() ) ), + column.getColumnSize( + dialect, + runtimeModelCreationContext.getMetadata() + ), // Always report as nullable as the identity column string usually includes the not null constraint - true, //column.isNullable() + true,//column.isNullable() true ) ); @@ -304,6 +329,10 @@ public class TemporaryTable implements Exportable, Contributable { dialect, runtimeModelCreationContext.getMetadata() ), + column.getColumnSize( + dialect, + runtimeModelCreationContext.getMetadata() + ), // We have to set the identity column after the root table insert column.isNullable() || identityColumn || hasOptimizer, !identityColumn && !hasOptimizer @@ -324,6 +353,10 @@ public class TemporaryTable implements Exportable, Contributable { dialect, runtimeModelCreationContext.getMetadata() ), + discriminator.getColumnSize( + dialect, + runtimeModelCreationContext.getMetadata() + ), // We have to set the identity column after the root table insert discriminator.isNullable() ) @@ -352,6 +385,10 @@ public class TemporaryTable implements Exportable, Contributable { dialect, runtimeModelCreationContext.getMetadata() ), + column.getColumnSize( + dialect, + runtimeModelCreationContext.getMetadata() + ), // Treat regular temporary table columns as nullable for simplicity true ) @@ -411,6 +448,7 @@ public class TemporaryTable implements Exportable, Contributable { "rn_", integerBasicType, rowNumberType, + Size.nil(), false, true ) @@ -433,6 +471,10 @@ public class TemporaryTable implements Exportable, Contributable { return columns; } + public List getColumnsForExport() { + return columnsForExport; + } + public TemporaryTableSessionUidColumn getSessionUidColumn() { return sessionUidColumn; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTableColumn.java b/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTableColumn.java index 28c34c6dbd..b46c49faa0 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTableColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTableColumn.java @@ -6,6 +6,7 @@ */ package org.hibernate.dialect.temptable; +import org.hibernate.engine.jdbc.Size; import org.hibernate.metamodel.mapping.JdbcMapping; /** @@ -19,6 +20,7 @@ public class TemporaryTableColumn { private final String columnName; private final JdbcMapping jdbcMapping; private final String sqlTypeName; + private final Size size; private final boolean nullable; private final boolean primaryKey; @@ -27,8 +29,9 @@ public class TemporaryTableColumn { String columnName, JdbcMapping jdbcMapping, String sqlTypeName, + Size size, boolean nullable) { - this( containingTable, columnName, jdbcMapping, sqlTypeName, nullable, false ); + this( containingTable, columnName, jdbcMapping, sqlTypeName, size, nullable, false ); } public TemporaryTableColumn( @@ -36,12 +39,14 @@ public class TemporaryTableColumn { String columnName, JdbcMapping jdbcMapping, String sqlTypeName, + Size size, boolean nullable, boolean primaryKey) { this.containingTable = containingTable; this.columnName = columnName; this.jdbcMapping = jdbcMapping; this.sqlTypeName = sqlTypeName; + this.size = size; this.nullable = nullable; this.primaryKey = primaryKey; } @@ -66,6 +71,10 @@ public class TemporaryTableColumn { return sqlTypeName; } + public Size getSize() { + return size; + } + public boolean isNullable() { return nullable; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTableSessionUidColumn.java b/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTableSessionUidColumn.java index f15581855a..c14d43878f 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTableSessionUidColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTableSessionUidColumn.java @@ -6,6 +6,7 @@ */ package org.hibernate.dialect.temptable; +import org.hibernate.engine.jdbc.Size; import org.hibernate.metamodel.mapping.JdbcMapping; /** @@ -15,12 +16,14 @@ public class TemporaryTableSessionUidColumn extends TemporaryTableColumn { public TemporaryTableSessionUidColumn( TemporaryTable containingTable, JdbcMapping jdbcMapping, - String sqlTypeName) { + String sqlTypeName, + Size size) { super( containingTable, TemporaryTableHelper.SESSION_ID_COLUMN_NAME, jdbcMapping, sqlTypeName, + size, false, true ); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index 6454ef7c1a..f0a3df880b 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -300,6 +300,7 @@ public class SessionFactoryImpl implements SessionFactoryImplementor { } identifierGenerators.put( model.getEntityName(), generator ); } ); + bootMetamodel.orderColumns( false ); bootMetamodel.validate(); LOG.debug( "Instantiated session factory" ); diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/DenormalizedTable.java b/hibernate-core/src/main/java/org/hibernate/mapping/DenormalizedTable.java index c7f6bb3ea4..093771480b 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/DenormalizedTable.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/DenormalizedTable.java @@ -11,6 +11,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; +import org.hibernate.Internal; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.relational.Namespace; import org.hibernate.internal.util.collections.JoinedIterator; @@ -22,6 +23,7 @@ import org.hibernate.internal.util.collections.JoinedList; public class DenormalizedTable extends Table { private final Table includedTable; + private List reorderedColumns; public DenormalizedTable( String contributor, @@ -88,11 +90,17 @@ public class DenormalizedTable extends Table { @Override @Deprecated public Iterator getColumnIterator() { + if ( reorderedColumns != null ) { + return reorderedColumns.iterator(); + } return new JoinedIterator<>( includedTable.getColumnIterator(), super.getColumnIterator() ); } @Override public Collection getColumns() { + if ( reorderedColumns != null ) { + return reorderedColumns; + } return new JoinedList<>( new ArrayList<>( includedTable.getColumns() ), new ArrayList<>( super.getColumns() ) ); } @@ -132,4 +140,14 @@ public class DenormalizedTable extends Table { public Table getIncludedTable() { return includedTable; } + + @Internal + @Override + public void reorderColumns(List columns) { + assert includedTable.getColumns().size() + super.getColumns().size() == columns.size() + && columns.containsAll( includedTable.getColumns() ) + && columns.containsAll( super.getColumns() ) + && reorderedColumns == null; + this.reorderedColumns = columns; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/PrimaryKey.java b/hibernate-core/src/main/java/org/hibernate/mapping/PrimaryKey.java index 9db98f7660..9688bf1419 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/PrimaryKey.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/PrimaryKey.java @@ -6,6 +6,10 @@ */ package org.hibernate.mapping; +import java.util.Arrays; +import java.util.List; + +import org.hibernate.Internal; import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.dialect.Dialect; import org.hibernate.internal.util.StringHelper; @@ -21,6 +25,8 @@ import org.jboss.logging.Logger; public class PrimaryKey extends Constraint { private static final Logger log = Logger.getLogger( PrimaryKey.class ); + private int[] originalOrder; + public PrimaryKey(Table table){ setTable( table ); } @@ -98,4 +104,38 @@ public class PrimaryKey extends Constraint { public String getExportIdentifier() { return StringHelper.qualify( getTable().getExportIdentifier(), "PK-" + getName() ); } + + public List getColumnsInOriginalOrder() { + if ( originalOrder == null ) { + return getColumns(); + } + final List columns = getColumns(); + final Column[] columnsInOriginalOrder = new Column[columns.size()]; + for ( int i = 0; i < columnsInOriginalOrder.length; i++ ) { + columnsInOriginalOrder[i] = columns.get( originalOrder[i] ); + } + return Arrays.asList( columnsInOriginalOrder ); + } + + @Internal + public void reorderColumns(List reorderedColumns) { + if ( originalOrder != null ) { + assert getColumns().equals( reorderedColumns ); + return; + } + assert getColumns().size() == reorderedColumns.size() && getColumns().containsAll( reorderedColumns ); + final List columns = getColumns(); + originalOrder = new int[columns.size()]; + for ( int i = 0; i < reorderedColumns.size(); i++ ) { + final Column reorderedColumn = reorderedColumns.get( i ); + originalOrder[i] = columns.indexOf( reorderedColumn ); + } + columns.clear(); + columns.addAll( reorderedColumns ); + } + + @Internal + public int[] getOriginalOrder() { + return originalOrder; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Table.java b/hibernate-core/src/main/java/org/hibernate/mapping/Table.java index 4f0a125e65..4424ec948e 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Table.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Table.java @@ -686,6 +686,15 @@ public class Table implements Serializable, ContributableDatabaseObject { return identifier == null ? null : identifier.render(); } + @Internal + public void reorderColumns(List columns) { + assert this.columns.size() == columns.size() && this.columns.values().containsAll( columns ); + this.columns.clear(); + for ( Column column : columns ) { + this.columns.put( column.getCanonicalName(), column ); + } + } + public static class ForeignKeyKey implements Serializable { private final String referencedClassName; private final Column[] columns; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/UserDefinedType.java b/hibernate-core/src/main/java/org/hibernate/mapping/UserDefinedType.java index e1aa148d87..1acaf47418 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/UserDefinedType.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/UserDefinedType.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.Map; import org.hibernate.HibernateException; +import org.hibernate.Internal; import org.hibernate.boot.Metadata; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.relational.ContributableDatabaseObject; @@ -40,6 +41,7 @@ public class UserDefinedType implements Serializable, ContributableDatabaseObjec private Identifier name; private final Map columns = new LinkedHashMap<>(); + private int[] orderMapping; private String comment; public UserDefinedType( @@ -255,4 +257,25 @@ public class UserDefinedType implements Serializable, ContributableDatabaseObjec } return qualifiedName.append( name.render() ).toString(); } + + @Internal + public void reorderColumns(List columns) { + if ( orderMapping != null ) { + return; + } + orderMapping = new int[columns.size()]; + int i = 0; + for ( Column column : this.columns.values() ) { + orderMapping[i++] = columns.indexOf( column ); + } + this.columns.clear(); + for ( Column column : columns ) { + this.columns.put( column.getCanonicalName(), column ); + } + } + + @Internal + public int[] getOrderMapping() { + return orderMapping; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorRecordStandard.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorRecordStandard.java index dd23798e7b..1263d2c4b7 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorRecordStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorRecordStandard.java @@ -25,19 +25,7 @@ public class EmbeddableInstantiatorRecordStandard extends AbstractPojoInstantiat super( javaType ); final Class[] componentTypes = ReflectHelper.getRecordComponentTypes( javaType ); - this.constructor = resolveConstructor( javaType, componentTypes ); - } - - protected static Constructor resolveConstructor(Class recordClass, Class[] componentTypes) { - try { - return recordClass.getConstructor( componentTypes ); - } - catch (NoSuchMethodException e) { - throw new IllegalArgumentException( - "Could not determine the canonical record constructor for: " + recordClass.getName(), - e - ); - } + this.constructor = ReflectHelper.getConstructor( javaType, componentTypes ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java index e5d5a20bbb..617d57cc53 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java @@ -240,7 +240,8 @@ public class EmbeddableMappingTypeImpl extends AbstractEmbeddableMapping impleme aggregateColumn.getSqlTypeCode() == SqlTypes.STRUCT ? aggregateColumn.getSqlType() : null, - this + this, + creationContext ) ); // Register the resolved type under its struct name and java class name diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java index 4e659aa32e..b5532c1100 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddedAttributeMapping.java @@ -292,10 +292,7 @@ public class EmbeddedAttributeMapping Clause clause, SqmToSqlAstConverter walker, SqlAstCreationState sqlAstCreationState) { - if ( embeddableMappingType.shouldSelectAggregateMapping() - // We always want to set the whole aggregate mapping in the SET clause if a single expression is given - // This usually happens when we try to set the aggregate to e.g. null or a parameter - || clause == Clause.SET && embeddableMappingType.getAggregateMapping() != null ) { + if ( embeddableMappingType.getAggregateMapping() != null ) { final SelectableMapping selection = embeddableMappingType.getAggregateMapping(); final NavigablePath navigablePath = tableGroup.getNavigablePath().append( getNavigableRole().getNavigableName() ); final TableReference tableReference = tableGroup.resolveTableReference( navigablePath, getContainingTableExpression() ); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java index 2af0d9b631..2675432f04 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java @@ -334,7 +334,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { final String tableName = determineTableName( table ); subclassTableNames.add( tableName ); String[] key = new String[idColumnSpan]; - List columns = table.getPrimaryKey().getColumns(); + List columns = table.getPrimaryKey().getColumnsInOriginalOrder(); for ( int k = 0; k < idColumnSpan; k++ ) { key[k] = columns.get(k).getQuotedName( dialect ); } @@ -354,7 +354,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { String joinTableName = determineTableName( joinTable ); subclassTableNames.add( joinTableName ); String[] key = new String[idColumnSpan]; - List columns = joinTable.getPrimaryKey().getColumns(); + List columns = joinTable.getPrimaryKey().getColumnsInOriginalOrder(); for ( int k = 0; k < idColumnSpan; k++ ) { key[k] = columns.get(k).getQuotedName( dialect ); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java index 6e65ebe178..1722b06c68 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java @@ -221,7 +221,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister { if ( !table.isAbstractUnionTable() ) { tableNames.add( determineTableName( table ) ); String[] key = new String[idColumnSpan]; - List columns = table.getPrimaryKey().getColumns(); + List columns = table.getPrimaryKey().getColumnsInOriginalOrder(); for ( int k = 0; k < idColumnSpan; k++ ) { key[k] = columns.get(k).getQuotedName( dialect ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/AggregateJdbcType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/AggregateJdbcType.java index b08c96041f..d35f89f2ef 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/AggregateJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/AggregateJdbcType.java @@ -9,6 +9,7 @@ package org.hibernate.type.descriptor.jdbc; import java.sql.SQLException; import org.hibernate.metamodel.mapping.EmbeddableMappingType; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.SqlTypes; import org.hibernate.type.descriptor.WrapperOptions; @@ -17,7 +18,10 @@ import org.hibernate.type.descriptor.WrapperOptions; */ public interface AggregateJdbcType extends JdbcType { - AggregateJdbcType resolveAggregateJdbcType(EmbeddableMappingType mappingType, String sqlType); + AggregateJdbcType resolveAggregateJdbcType( + EmbeddableMappingType mappingType, + String sqlType, + RuntimeModelCreationContext creationContext); EmbeddableMappingType getEmbeddableMappingType(); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JsonJdbcType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JsonJdbcType.java index 447c538e93..ba6c735031 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JsonJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JsonJdbcType.java @@ -13,6 +13,7 @@ import java.sql.SQLException; import org.hibernate.dialect.JsonHelper; import org.hibernate.metamodel.mapping.EmbeddableMappingType; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.SqlTypes; import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueExtractor; @@ -58,7 +59,10 @@ public class JsonJdbcType implements AggregateJdbcType { } @Override - public AggregateJdbcType resolveAggregateJdbcType(EmbeddableMappingType mappingType, String sqlType) { + public AggregateJdbcType resolveAggregateJdbcType( + EmbeddableMappingType mappingType, + String sqlType, + RuntimeModelCreationContext creationContext) { return new JsonJdbcType( mappingType ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/OracleJsonBlobJdbcType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/OracleJsonBlobJdbcType.java index be22de7c26..a8bdb178fb 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/OracleJsonBlobJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/OracleJsonBlobJdbcType.java @@ -15,6 +15,7 @@ import java.sql.SQLException; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.JsonHelper; import org.hibernate.metamodel.mapping.EmbeddableMappingType; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.SqlTypes; import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueExtractor; @@ -65,7 +66,10 @@ public class OracleJsonBlobJdbcType implements AggregateJdbcType { } @Override - public AggregateJdbcType resolveAggregateJdbcType(EmbeddableMappingType mappingType, String sqlType) { + public AggregateJdbcType resolveAggregateJdbcType( + EmbeddableMappingType mappingType, + String sqlType, + RuntimeModelCreationContext creationContext) { return new OracleJsonBlobJdbcType( mappingType ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/XmlAsStringJdbcType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/XmlAsStringJdbcType.java index 928d5518ae..eb17a98a0e 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/XmlAsStringJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/XmlAsStringJdbcType.java @@ -12,6 +12,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import org.hibernate.metamodel.mapping.EmbeddableMappingType; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.SqlTypes; import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueExtractor; @@ -34,7 +35,10 @@ public class XmlAsStringJdbcType extends XmlJdbcType { } @Override - public AggregateJdbcType resolveAggregateJdbcType(EmbeddableMappingType mappingType, String sqlType) { + public AggregateJdbcType resolveAggregateJdbcType( + EmbeddableMappingType mappingType, + String sqlType, + RuntimeModelCreationContext creationContext) { return new XmlAsStringJdbcType( mappingType ); } @@ -95,7 +99,8 @@ public class XmlAsStringJdbcType extends XmlJdbcType { } @Override - protected X doExtract(CallableStatement statement, String name, WrapperOptions options) throws SQLException { + protected X doExtract(CallableStatement statement, String name, WrapperOptions options) + throws SQLException { return getObject( statement.getString( name ), options ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/XmlJdbcType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/XmlJdbcType.java index a015cdeb05..4d6eb0a6ef 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/XmlJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/XmlJdbcType.java @@ -14,6 +14,7 @@ import java.sql.SQLXML; import org.hibernate.dialect.XmlHelper; import org.hibernate.metamodel.mapping.EmbeddableMappingType; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.SqlTypes; import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueExtractor; @@ -54,7 +55,10 @@ public class XmlJdbcType implements AggregateJdbcType { } @Override - public AggregateJdbcType resolveAggregateJdbcType(EmbeddableMappingType mappingType, String sqlType) { + public AggregateJdbcType resolveAggregateJdbcType( + EmbeddableMappingType mappingType, + String sqlType, + RuntimeModelCreationContext creationContext) { return new XmlJdbcType( mappingType ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/spi/JdbcTypeRegistry.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/spi/JdbcTypeRegistry.java index e24c9ef396..1b1bafdd22 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/spi/JdbcTypeRegistry.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/spi/JdbcTypeRegistry.java @@ -9,10 +9,9 @@ package org.hibernate.type.descriptor.jdbc.spi; import java.io.Serializable; import java.util.Locale; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BiFunction; import org.hibernate.metamodel.mapping.EmbeddableMappingType; -import org.hibernate.type.SqlTypes; +import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.type.descriptor.JdbcTypeNameMapper; import org.hibernate.type.descriptor.jdbc.AggregateJdbcType; import org.hibernate.type.descriptor.jdbc.JdbcType; @@ -121,7 +120,8 @@ public class JdbcTypeRegistry implements JdbcTypeBaseline.BaselineTarget, Serial public AggregateJdbcType resolveAggregateDescriptor( int jdbcTypeCode, String typeName, - EmbeddableMappingType embeddableMappingType) { + EmbeddableMappingType embeddableMappingType, + RuntimeModelCreationContext creationContext) { final String registrationKey; if ( typeName != null ) { registrationKey = typeName.toLowerCase( Locale.ROOT ); @@ -134,7 +134,11 @@ public class JdbcTypeRegistry implements JdbcTypeBaseline.BaselineTarget, Serial // which are prefixed with the aggregateMapping. // Since the columnExpression is used as key for mutation parameters, this is important. // We could get rid of this if ColumnValueParameter drops the ColumnReference - return aggregateJdbcType.resolveAggregateJdbcType( embeddableMappingType, typeName ); + return aggregateJdbcType.resolveAggregateJdbcType( + embeddableMappingType, + typeName, + creationContext + ); } return aggregateJdbcType; } @@ -154,7 +158,8 @@ public class JdbcTypeRegistry implements JdbcTypeBaseline.BaselineTarget, Serial final AggregateJdbcType aggregateJdbcType = (AggregateJdbcType) descriptor; final AggregateJdbcType resolvedJdbcType = aggregateJdbcType.resolveAggregateJdbcType( embeddableMappingType, - typeName + typeName, + creationContext ); if ( registrationKey != null ) { aggregateDescriptorMap.put( registrationKey, resolvedJdbcType ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/enumerated/EnumeratedSmokeTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/enumerated/EnumeratedSmokeTest.java index 6b68377763..ee74d104ef 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/enumerated/EnumeratedSmokeTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/enumerated/EnumeratedSmokeTest.java @@ -59,6 +59,7 @@ public class EnumeratedSmokeTest extends BaseUnitTestCase { final MetadataImplementor mappings = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( EntityWithEnumeratedAttributes.class ) .buildMetadata(); + mappings.orderColumns( false ); mappings.validate(); final JdbcTypeRegistry jdbcTypeRegistry = mappings.getTypeConfiguration().getJdbcTypeRegistry(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/JoinColumnOverrideTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/JoinColumnOverrideTest.java index 1416c71e84..38a66e0f30 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/JoinColumnOverrideTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/JoinColumnOverrideTest.java @@ -8,10 +8,10 @@ package org.hibernate.orm.test.annotations.id; import java.util.List; -import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.cfg.AvailableSettings; import org.hibernate.tool.schema.internal.SchemaCreatorImpl; @@ -33,10 +33,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @BaseUnitTest public class JoinColumnOverrideTest { - private static final String expectedSqlPointyTooth = "create table PointyTooth (id numeric(128,0) not null, " + - "bunny_id numeric(128,0), primary key (id))"; - private static final String expectedSqlTwinkleToes = "create table TwinkleToes (id numeric(128,0) not null, " + - "bunny_id numeric(128,0), primary key (id))"; + private static final String expectedSqlPointyTooth = "create table PointyTooth (bunny_id numeric(128,0), " + + "id numeric(128,0) not null, primary key (id))"; + private static final String expectedSqlTwinkleToes = "create table TwinkleToes (bunny_id numeric(128,0), " + + "id numeric(128,0) not null, primary key (id))"; @Test @TestForIssue(jiraKey = "ANN-748") @@ -46,11 +46,13 @@ public class JoinColumnOverrideTest { .build(); try { - Metadata metadata = new MetadataSources( ssr ) + MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( Bunny.class ) .addAnnotatedClass( PointyTooth.class ) .addAnnotatedClass( TwinkleToes.class ) .buildMetadata(); + metadata.orderColumns( true ); + metadata.validate(); boolean foundPointyToothCreate = false; boolean foundTwinkleToesCreate = false; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/sequences/JoinColumnOverrideTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/sequences/JoinColumnOverrideTest.java index 4e83f9c491..03ed806ff7 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/sequences/JoinColumnOverrideTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/sequences/JoinColumnOverrideTest.java @@ -10,10 +10,10 @@ package org.hibernate.orm.test.annotations.id.sequences; import java.util.List; -import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.cfg.AvailableSettings; import org.hibernate.tool.schema.internal.SchemaCreatorImpl; @@ -36,10 +36,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @BaseUnitTest public class JoinColumnOverrideTest { - private static final String expectedSqlPointyTooth = "create table PointyTooth (id numeric(128,0) not null, " + - "bunny_id numeric(128,0), primary key (id))"; - private static final String expectedSqlTwinkleToes = "create table TwinkleToes (id numeric(128,0) not null, " + - "bunny_id numeric(128,0), primary key (id))"; + private static final String expectedSqlPointyTooth = "create table PointyTooth (bunny_id numeric(128,0), " + + "id numeric(128,0) not null, primary key (id))"; + private static final String expectedSqlTwinkleToes = "create table TwinkleToes (bunny_id numeric(128,0), " + + "id numeric(128,0) not null, primary key (id))"; @Test @TestForIssue(jiraKey = "ANN-748") @@ -48,11 +48,13 @@ public class JoinColumnOverrideTest { .applySetting( AvailableSettings.DIALECT, "SQLServer" ) .build(); try { - Metadata metadata = new MetadataSources( ssr ) + MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( Bunny.class ) .addAnnotatedClass( PointyTooth.class ) .addAnnotatedClass( TwinkleToes.class ) .buildMetadata(); + metadata.orderColumns( true ); + metadata.validate(); boolean foundPointyToothCreate = false; boolean foundTwinkleToesCreate = false; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/bootstrap/binding/annotations/override/InheritedAttributeOverridingTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/bootstrap/binding/annotations/override/InheritedAttributeOverridingTest.java index f82e5831f5..4cc272de0c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/bootstrap/binding/annotations/override/InheritedAttributeOverridingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/bootstrap/binding/annotations/override/InheritedAttributeOverridingTest.java @@ -48,6 +48,7 @@ public class InheritedAttributeOverridingTest extends BaseUnitTestCase { .addAnnotatedClass( B.class ) .buildMetadata(); + ( (MetadataImplementor) metadata ).orderColumns( false ); ( (MetadataImplementor) metadata ).validate(); } @@ -59,6 +60,7 @@ public class InheritedAttributeOverridingTest extends BaseUnitTestCase { .addAnnotatedClass( D.class ) .buildMetadata(); + ( (MetadataImplementor) metadata ).orderColumns( false ); ( (MetadataImplementor) metadata ).validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/foreignkeys/disabled/DisabledForeignKeyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/foreignkeys/disabled/DisabledForeignKeyTest.java index 94e4596c72..f646a109a3 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/foreignkeys/disabled/DisabledForeignKeyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/foreignkeys/disabled/DisabledForeignKeyTest.java @@ -44,6 +44,7 @@ public class DisabledForeignKeyTest extends BaseUnitTestCase { sources.addAnnotatedClass( ManyToManyTarget.class ); final MetadataImplementor metadata = (MetadataImplementor) sources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaExport().execute( @@ -84,6 +85,7 @@ public class DisabledForeignKeyTest extends BaseUnitTestCase { sources.addAnnotatedClass( ManyToManyTarget.class ); final MetadataImplementor metadata = (MetadataImplementor) sources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); // export the schema diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/SequenceNamingStrategyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/SequenceNamingStrategyTest.java index 3548cd7303..9d5e6e5f65 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/SequenceNamingStrategyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/SequenceNamingStrategyTest.java @@ -150,6 +150,7 @@ public class SequenceNamingStrategyTest { metadataSources.addAnnotatedClass( entityClass ); final MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); consumer.accept( metadata ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/TableNamingStrategyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/TableNamingStrategyTest.java index 22226a563e..801920b72f 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/TableNamingStrategyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/enhanced/TableNamingStrategyTest.java @@ -131,6 +131,7 @@ public class TableNamingStrategyTest { metadataSources.addAnnotatedClass( entityClass ); final MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); consumer.accept( metadata ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/sequence/SequenceExportTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/sequence/SequenceExportTest.java index 0f5b6de74f..f620b42fb9 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/id/sequence/SequenceExportTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/sequence/SequenceExportTest.java @@ -53,6 +53,7 @@ public class SequenceExportTest extends BaseUnitTestCase { .addAnnotatedClass( Entity1.class ) .addAnnotatedClass( Entity2.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); int namespaceCount = 0; @@ -76,6 +77,7 @@ public class SequenceExportTest extends BaseUnitTestCase { .addAnnotatedClass( Entity3.class ) .addAnnotatedClass( Entity4.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); int namespaceCount = 0; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/uuid/GeneratedValueTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/uuid/GeneratedValueTest.java index 2e7a0c26c8..30da7bd0eb 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/id/uuid/GeneratedValueTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/uuid/GeneratedValueTest.java @@ -15,11 +15,10 @@ import jakarta.persistence.Table; import org.hibernate.Session; import org.hibernate.SessionFactory; -import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.internal.MetadataImpl; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.cfg.AvailableSettings; import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.UUIDGenerator; @@ -46,7 +45,8 @@ public class GeneratedValueTest { .applySetting( AvailableSettings.HBM2DDL_AUTO, "create-drop" ) .build(); try { - MetadataImpl metadata = (MetadataImpl) new MetadataSources( ssr ).addAnnotatedClass( TheEntity.class ).buildMetadata(); + MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ).addAnnotatedClass( TheEntity.class ).buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); PersistentClass entityBinding = metadata.getEntityBinding( TheEntity.class.getName() ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AndNationalizedTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AndNationalizedTests.java index d078e0b6e7..72215c0763 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AndNationalizedTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/AndNationalizedTests.java @@ -15,9 +15,9 @@ import jakarta.persistence.Table; import org.hibernate.annotations.Nationalized; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.internal.MetadataImpl; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.dialect.DB2Dialect; import org.hibernate.dialect.Dialect; import org.hibernate.mapping.PersistentClass; @@ -42,7 +42,8 @@ public class AndNationalizedTests extends BaseUnitTestCase { StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().build(); try { Metadata metadata = new MetadataSources( ssr ).addAnnotatedClass( TestEntity.class ).buildMetadata(); - ( (MetadataImpl) metadata ).validate(); + ( (MetadataImplementor) metadata ).orderColumns( false ); + ( (MetadataImplementor) metadata ).validate(); final PersistentClass entityBinding = metadata.getEntityBinding( TestEntity.class.getName() ); final Dialect dialect = metadata.getDatabase().getDialect(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionCompositeElementExplicitConversionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionCompositeElementExplicitConversionTest.java index c2c4c54aef..26681480e1 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionCompositeElementExplicitConversionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/converted/converter/elementCollection/CollectionCompositeElementExplicitConversionTest.java @@ -64,6 +64,7 @@ public class CollectionCompositeElementExplicitConversionTest { .addAnnotatedClass( Traits.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); final PersistentClass entityBinding = metadata.getEntityBinding( Disguise.class.getName() ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/composite/CompositeNaturalIdMappingTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/composite/CompositeNaturalIdMappingTest.java index 3ae978d7ef..5ec54b4dda 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/composite/CompositeNaturalIdMappingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/composite/CompositeNaturalIdMappingTest.java @@ -31,6 +31,7 @@ public class CompositeNaturalIdMappingTest { .addAnnotatedClass( PostalCarrier.class ) .addAnnotatedClass( PostalCode.class ) .buildMetadata(); + ( (MetadataImplementor) meta ).orderColumns( false ); ( (MetadataImplementor) meta ).validate(); } finally { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/compound/CompoundNaturalIdMappingTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/compound/CompoundNaturalIdMappingTest.java index cfa20ff721..d7c6379e4d 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/compound/CompoundNaturalIdMappingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/naturalid/compound/CompoundNaturalIdMappingTest.java @@ -8,7 +8,6 @@ package org.hibernate.orm.test.mapping.naturalid.compound; import java.util.List; -import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; @@ -18,13 +17,10 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.NaturalIdMapping; import org.hibernate.metamodel.mapping.SingularAttributeMapping; -import org.hibernate.persister.entity.EntityPersister; import org.hibernate.testing.TestForIssue; import org.junit.jupiter.api.Test; -import org.hamcrest.Matchers; - import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -44,6 +40,7 @@ public class CompoundNaturalIdMappingTest { .addAnnotatedClass( PostalCarrier.class ) .addAnnotatedClass( Country.class ) .buildMetadata(); + ( (MetadataImplementor) meta ).orderColumns( false ); ( (MetadataImplementor) meta ).validate(); final SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) meta.buildSessionFactory(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/namingstrategy/ejb3joincolumn/Tests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/namingstrategy/ejb3joincolumn/Tests.java index 1bc37977ee..1922ac5fa1 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/namingstrategy/ejb3joincolumn/Tests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/namingstrategy/ejb3joincolumn/Tests.java @@ -55,6 +55,7 @@ public class Tests { metadataBuilder.applyPhysicalNamingStrategy( PhysicalNamingStrategyImpl.INSTANCE ); final Metadata metadata = metadataBuilder.build(); + ( (MetadataImplementor) metadata ).orderColumns( false ); ( (MetadataImplementor) metadata ).validate(); final PersistentClass languageBinding = metadata.getEntityBinding( Language.class.getName() ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/quote/ColumnDefinitionQuotingTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/quote/ColumnDefinitionQuotingTest.java index 2aa5b1fed8..50d207a0b6 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/quote/ColumnDefinitionQuotingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/quote/ColumnDefinitionQuotingTest.java @@ -46,6 +46,7 @@ public class ColumnDefinitionQuotingTest { MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( E1.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); PersistentClass entityBinding = metadata.getEntityBinding( E1.class.getName() ); @@ -72,6 +73,7 @@ public class ColumnDefinitionQuotingTest { MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( E1.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); PersistentClass entityBinding = metadata.getEntityBinding( E1.class.getName() ); @@ -108,6 +110,7 @@ public class ColumnDefinitionQuotingTest { MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( E2.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); PersistentClass entityBinding = metadata.getEntityBinding( E2.class.getName() ); @@ -134,6 +137,7 @@ public class ColumnDefinitionQuotingTest { MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( E2.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); PersistentClass entityBinding = metadata.getEntityBinding( E2.class.getName() ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schematools/TestExtraPhysicalTableTypes.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schematools/TestExtraPhysicalTableTypes.java index 191388042b..3ae3c7482e 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schematools/TestExtraPhysicalTableTypes.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schematools/TestExtraPhysicalTableTypes.java @@ -172,6 +172,7 @@ public class TestExtraPhysicalTableTypes { } metadata = (MetadataImplementor) new MetadataSources( ssr ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/AlterTableQuoteDefaultSchemaTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/AlterTableQuoteDefaultSchemaTest.java index de8351fe13..9ca858bec2 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/AlterTableQuoteDefaultSchemaTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/AlterTableQuoteDefaultSchemaTest.java @@ -112,6 +112,7 @@ public class AlterTableQuoteDefaultSchemaTest extends AbstractAlterTableQuoteSch metadataSources.addAnnotatedClass( MyEntity.class ); final MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() @@ -154,6 +155,7 @@ public class AlterTableQuoteDefaultSchemaTest extends AbstractAlterTableQuoteSch metadataSources.addAnnotatedClass( MyEntityUpdated.class ); final MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/AlterTableQuoteSpecifiedSchemaTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/AlterTableQuoteSpecifiedSchemaTest.java index c9b9022eda..ba0120ef46 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/AlterTableQuoteSpecifiedSchemaTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/AlterTableQuoteSpecifiedSchemaTest.java @@ -103,6 +103,7 @@ public class AlterTableQuoteSpecifiedSchemaTest extends AbstractAlterTableQuoteS final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( MyEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() @@ -133,6 +134,7 @@ public class AlterTableQuoteSpecifiedSchemaTest extends AbstractAlterTableQuoteS final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( MyEntityUpdated.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/CommentGenerationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/CommentGenerationTest.java index 9f03350764..d72a59a68a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/CommentGenerationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/CommentGenerationTest.java @@ -48,6 +48,7 @@ public class CommentGenerationTest { final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addResource( resource ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/ConnectionsReleaseTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/ConnectionsReleaseTest.java index 5a0cc6f4d1..c951521153 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/ConnectionsReleaseTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/ConnectionsReleaseTest.java @@ -67,6 +67,7 @@ public class ConnectionsReleaseTest extends BaseUnitTestCase { metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( Thing.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/HANASchemaMigrationTargetScriptCreationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/HANASchemaMigrationTargetScriptCreationTest.java index 740ed3a243..1c58b818e9 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/HANASchemaMigrationTargetScriptCreationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/HANASchemaMigrationTargetScriptCreationTest.java @@ -86,6 +86,7 @@ public class HANASchemaMigrationTargetScriptCreationTest extends BaseCoreFunctio MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( serviceRegistry ) .addAnnotatedClass( TestEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaExport().drop( EnumSet.of( TargetType.DATABASE, TargetType.STDOUT ), metadata ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/QuotedTableNameSchemaUpdateTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/QuotedTableNameSchemaUpdateTest.java index f3e3a28a3b..b9e3e7980f 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/QuotedTableNameSchemaUpdateTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/QuotedTableNameSchemaUpdateTest.java @@ -66,6 +66,7 @@ public class QuotedTableNameSchemaUpdateTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( QuotedTable.class ); MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaExport() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/QuotedTableNameWithForeignKeysSchemaUpdateTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/QuotedTableNameWithForeignKeysSchemaUpdateTest.java index 63aa44e4ac..04ff3d5fcb 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/QuotedTableNameWithForeignKeysSchemaUpdateTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/QuotedTableNameWithForeignKeysSchemaUpdateTest.java @@ -35,6 +35,7 @@ public class QuotedTableNameWithForeignKeysSchemaUpdateTest extends BaseUnitTest final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addResource( "org/hibernate/orm/test/schemaupdate/UserGroup.hbm.xml" ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate().execute( EnumSet.of( TargetType.DATABASE ), metadata ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaCreationToOutputScriptTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaCreationToOutputScriptTest.java index 9f0cbb1642..be1c5499c2 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaCreationToOutputScriptTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaCreationToOutputScriptTest.java @@ -91,6 +91,7 @@ public class SchemaCreationToOutputScriptTest { .addAnnotatedClass( MyEntity.class ) .addAnnotatedClass( MySecondEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaDropTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaDropTest.java index 5dba3091a7..183f889f30 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaDropTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaDropTest.java @@ -55,6 +55,7 @@ public class SchemaDropTest extends BaseUnitTestCase implements ExecutionOptions serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( Environment.getProperties() ); metadata = (MetadataImplementor) new MetadataSources( serviceRegistry ) .addAnnotatedClass( MyEntity.class ).buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaDropToOutputScriptTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaDropToOutputScriptTest.java index 5783b73f96..1a92581092 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaDropToOutputScriptTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaDropToOutputScriptTest.java @@ -89,6 +89,7 @@ public class SchemaDropToOutputScriptTest { .addAnnotatedClass( MyEntity.class ) .addAnnotatedClass( MySecondEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaExportTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaExportTest.java index fa9f153bac..a224e2e502 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaExportTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaExportTest.java @@ -52,6 +52,7 @@ public class SchemaExportTest extends BaseUnitTestCase { metadata = (MetadataImplementor) new MetadataSources( serviceRegistry ) .addResource( "org/hibernate/orm/test/schemaupdate/mapping.hbm.xml" ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaExport().drop( EnumSet.of( TargetType.DATABASE, TargetType.STDOUT ), metadata ); @@ -154,6 +155,7 @@ public class SchemaExportTest extends BaseUnitTestCase { final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( serviceRegistry ) .addResource( "org/hibernate/orm/test/schemaupdate/mapping2.hbm.xml" ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); final SchemaExport schemaExport = new SchemaExport(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaMigrationTargetScriptCreationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaMigrationTargetScriptCreationTest.java index acf15652b2..0a2e5cf456 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaMigrationTargetScriptCreationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaMigrationTargetScriptCreationTest.java @@ -72,6 +72,7 @@ public class SchemaMigrationTargetScriptCreationTest extends BaseCoreFunctionalT MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( serviceRegistry ) .addAnnotatedClass( TestEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaExport().drop( EnumSet.of( TargetType.DATABASE, TargetType.STDOUT ), metadata ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaMigrationToOutputScriptTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaMigrationToOutputScriptTest.java index a0d4fc7e95..9063fd33eb 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaMigrationToOutputScriptTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaMigrationToOutputScriptTest.java @@ -104,6 +104,7 @@ public class SchemaMigrationToOutputScriptTest { .addAnnotatedClass( MyEntity.class ) .addAnnotatedClass( MySecondEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateDelimiterTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateDelimiterTest.java index 78fb92026b..9f68c92ad5 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateDelimiterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateDelimiterTest.java @@ -49,6 +49,7 @@ public class SchemaUpdateDelimiterTest { final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( TestEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateFormatterTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateFormatterTest.java index ee7db96591..24b1da290d 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateFormatterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateFormatterTest.java @@ -49,6 +49,7 @@ public class SchemaUpdateFormatterTest extends BaseUnitTestCase { final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( TestEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateGeneratingOnlyScriptFileTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateGeneratingOnlyScriptFileTest.java index 02ee666526..3f8100c855 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateGeneratingOnlyScriptFileTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateGeneratingOnlyScriptFileTest.java @@ -48,6 +48,7 @@ public class SchemaUpdateGeneratingOnlyScriptFileTest { final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( TestEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateJoinColumnNoConstraintSecondaryTableTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateJoinColumnNoConstraintSecondaryTableTest.java index a64fe347d5..0d6f60496c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateJoinColumnNoConstraintSecondaryTableTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateJoinColumnNoConstraintSecondaryTableTest.java @@ -13,8 +13,6 @@ import jakarta.persistence.ConstraintMode; import jakarta.persistence.Entity; import jakarta.persistence.ForeignKey; import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; import jakarta.persistence.SecondaryTable; import org.hibernate.boot.MetadataSources; @@ -66,6 +64,7 @@ public class SchemaUpdateJoinColumnNoConstraintSecondaryTableTest extends BaseUn final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( Parent.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateJoinColumnNoConstraintSecondaryTablesTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateJoinColumnNoConstraintSecondaryTablesTest.java index ff58644769..ea56bc233e 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateJoinColumnNoConstraintSecondaryTablesTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateJoinColumnNoConstraintSecondaryTablesTest.java @@ -64,6 +64,7 @@ public class SchemaUpdateJoinColumnNoConstraintSecondaryTablesTest extends BaseU final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( Parent.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateJoinColumnNoConstraintTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateJoinColumnNoConstraintTest.java index 406bafdb95..50858c2a6e 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateJoinColumnNoConstraintTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateJoinColumnNoConstraintTest.java @@ -56,6 +56,7 @@ public class SchemaUpdateJoinColumnNoConstraintTest extends BaseUnitTestCase { .addAnnotatedClass( Parent.class ) .addAnnotatedClass( Child.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateSQLServerTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateSQLServerTest.java index 722de68c89..4058cb349a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateSQLServerTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateSQLServerTest.java @@ -124,6 +124,7 @@ public class SchemaUpdateSQLServerTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( InheritanceSecondChildEntity.class ); metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateTest.java index fccf44f2b9..47b1ecb296 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateTest.java @@ -111,6 +111,7 @@ public class SchemaUpdateTest { metadataSources.addAnnotatedClass( InheritanceSecondChildEntity.class ); metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); // Databases that use case-insensitive quoted identifiers need to be skipped. diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateWithUseJdbcMetadataDefaultsSettingToFalseAndQuotedNameTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateWithUseJdbcMetadataDefaultsSettingToFalseAndQuotedNameTest.java index f167aa99ac..806e447eba 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateWithUseJdbcMetadataDefaultsSettingToFalseAndQuotedNameTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateWithUseJdbcMetadataDefaultsSettingToFalseAndQuotedNameTest.java @@ -62,6 +62,7 @@ public class SchemaUpdateWithUseJdbcMetadataDefaultsSettingToFalseAndQuotedNameT metadataSources.addAnnotatedClass( AnotherTestEntity.class ); metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateWithUseJdbcMetadataDefaultsSettingToFalseTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateWithUseJdbcMetadataDefaultsSettingToFalseTest.java index 7cee765441..6d6aab3c5c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateWithUseJdbcMetadataDefaultsSettingToFalseTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateWithUseJdbcMetadataDefaultsSettingToFalseTest.java @@ -63,6 +63,7 @@ public class SchemaUpdateWithUseJdbcMetadataDefaultsSettingToFalseTest { metadataSources.addAnnotatedClass( TestEntity.class ); metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateWithViewsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateWithViewsTest.java index 0733fd4667..1ae261ddb9 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateWithViewsTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SchemaUpdateWithViewsTest.java @@ -61,6 +61,7 @@ public class SchemaUpdateWithViewsTest extends BaseNonConfigCoreFunctionalTestCa metadata = (MetadataImplementor) new MetadataSources( serviceRegistry ) .addAnnotatedClass( MyEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SequenceReadingTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SequenceReadingTest.java index e001979243..1681d3d08f 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SequenceReadingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SequenceReadingTest.java @@ -48,6 +48,7 @@ public class SequenceReadingTest extends BaseCoreFunctionalTestCase { final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( MyEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); try { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SpannerSchemaCreationColumnTypesTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SpannerSchemaCreationColumnTypesTest.java index ba0d157830..473c58ff8a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SpannerSchemaCreationColumnTypesTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SpannerSchemaCreationColumnTypesTest.java @@ -54,6 +54,7 @@ public class SpannerSchemaCreationColumnTypesTest { metadataSources.addAnnotatedClass( TestEntity.class ); metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SqlServerQuoteSchemaTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SqlServerQuoteSchemaTest.java index becb4dc58a..2b0e745279 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SqlServerQuoteSchemaTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/SqlServerQuoteSchemaTest.java @@ -106,6 +106,7 @@ public class SqlServerQuoteSchemaTest extends BaseCoreFunctionalTestCase { final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( MyEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() @@ -136,6 +137,7 @@ public class SqlServerQuoteSchemaTest extends BaseCoreFunctionalTestCase { final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( MyEntityUpdated.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/derivedid/ColumnLengthTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/derivedid/ColumnLengthTest.java index f4133b237c..532b4e79e9 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/derivedid/ColumnLengthTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/derivedid/ColumnLengthTest.java @@ -60,6 +60,7 @@ public class ColumnLengthTest extends BaseUnitTestCase { .addAnnotatedClass( Employee.class ) .addAnnotatedClass( Dependent.class ) .buildMetadata(); + metadata.orderColumns( true ); metadata.validate(); } @@ -80,7 +81,7 @@ public class ColumnLengthTest extends BaseUnitTestCase { assertTrue( checkCommandIsGenerated( commands, - "create table DEPENDENT (name varchar(255) not null, FK1 varchar(32) not null, FK2 varchar(10) not null, primary key (FK1, FK2, name));" + "create table DEPENDENT (FK2 varchar(10) not null, FK1 varchar(32) not null, name varchar(255) not null, primary key (FK1, FK2, name));" ) ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/ForeignKeyDropTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/ForeignKeyDropTest.java index 8ebf9054a7..e62ef4c0f6 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/ForeignKeyDropTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/ForeignKeyDropTest.java @@ -65,6 +65,7 @@ public class ForeignKeyDropTest extends BaseUnitTestCase { .addAnnotatedClass( ParentEntity.class ) .addAnnotatedClass( ChildEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); schemaExport = new SchemaExport().setHaltOnError( false ).setOutputFile( output.getAbsolutePath() ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/ForeignKeyGenerationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/ForeignKeyGenerationTest.java index 16cbe85a39..dd0aa210fe 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/ForeignKeyGenerationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/ForeignKeyGenerationTest.java @@ -158,6 +158,7 @@ public class ForeignKeyGenerationTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( c ); } metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaExport() .setHaltOnError( true ) diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/ForeignKeyMigrationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/ForeignKeyMigrationTest.java index 824c27df8e..099d3cfa27 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/ForeignKeyMigrationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/ForeignKeyMigrationTest.java @@ -42,6 +42,7 @@ public class ForeignKeyMigrationTest extends BaseUnitTestCase { .addAnnotatedClass( Box.class ) .addAnnotatedClass( Thing.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); // first create the schema... diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/JoinedInheritanceForeignKeyTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/JoinedInheritanceForeignKeyTest.java index f69a75da82..55ffa25279 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/JoinedInheritanceForeignKeyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/JoinedInheritanceForeignKeyTest.java @@ -122,6 +122,7 @@ public class JoinedInheritanceForeignKeyTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( c ); } metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaExport() .setHaltOnError( true ) diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/SchemaUpdateWithKeywordAutoQuotingEnabledTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/SchemaUpdateWithKeywordAutoQuotingEnabledTest.java index 20c6f769b6..6fe9b0432e 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/SchemaUpdateWithKeywordAutoQuotingEnabledTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/SchemaUpdateWithKeywordAutoQuotingEnabledTest.java @@ -50,6 +50,7 @@ public class SchemaUpdateWithKeywordAutoQuotingEnabledTest extends BaseUnitTestC final MetadataSources metadataSources = new MetadataSources( ssr ); metadataSources.addAnnotatedClass( Match.class ); metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); try { createSchema(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/crossschema/CrossSchemaForeignKeyGenerationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/crossschema/CrossSchemaForeignKeyGenerationTest.java index f1e792e272..a0b9d4d488 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/crossschema/CrossSchemaForeignKeyGenerationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/crossschema/CrossSchemaForeignKeyGenerationTest.java @@ -87,6 +87,7 @@ public class CrossSchemaForeignKeyGenerationTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( SchemaTwoEntity.class ); MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaExport().setHaltOnError( true ) @@ -110,6 +111,7 @@ public class CrossSchemaForeignKeyGenerationTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( SchemaTwoEntity.class ); MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaExport() @@ -136,6 +138,7 @@ public class CrossSchemaForeignKeyGenerationTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( SchemaTwoEntity.class ); MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); final Database database = metadata.getDatabase(); @@ -205,6 +208,7 @@ public class CrossSchemaForeignKeyGenerationTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( SchemaTwoEntity.class ); MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); final HibernateSchemaManagementTool tool = (HibernateSchemaManagementTool) ssr.getService( SchemaManagementTool.class ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/definition/AbstractForeignKeyDefinitionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/definition/AbstractForeignKeyDefinitionTest.java index c6cd33e2f2..f64201e21f 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/definition/AbstractForeignKeyDefinitionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/foreignkeys/definition/AbstractForeignKeyDefinitionTest.java @@ -58,6 +58,7 @@ public abstract class AbstractForeignKeyDefinitionTest extends BaseUnitTestCase metadataSources.addAnnotatedClass( c ); } metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaExport() .setHaltOnError( true ) diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idbag/IdBagSequenceTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idbag/IdBagSequenceTest.java index 96278d52af..318fc6bf1b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idbag/IdBagSequenceTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idbag/IdBagSequenceTest.java @@ -46,6 +46,7 @@ public class IdBagSequenceTest extends BaseUnitTestCase { final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addResource( "org/hibernate/orm/test/schemaupdate/idbag/Mappings.hbm.xml" ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceGenerationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceGenerationTest.java index 5537b67322..e27ab6940b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceGenerationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceGenerationTest.java @@ -56,6 +56,7 @@ public class SequenceGenerationTest extends BaseUnitTestCase { metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( TestEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceGeneratorIncrementTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceGeneratorIncrementTest.java index 8f424552e2..cfac553f94 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceGeneratorIncrementTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceGeneratorIncrementTest.java @@ -230,6 +230,7 @@ public class SequenceGeneratorIncrementTest { metadataSources.addResource( hbm ); } metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceGeneratorsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceGeneratorsTest.java index 83e905f2c9..06daea51ba 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceGeneratorsTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/SequenceGeneratorsTest.java @@ -57,6 +57,7 @@ public class SequenceGeneratorsTest extends BaseUnitTestCase { metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( TestEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/TableGeneratorTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/TableGeneratorTest.java index 67bb14bfd4..0e28058999 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/TableGeneratorTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/TableGeneratorTest.java @@ -60,6 +60,7 @@ public class TableGeneratorTest extends BaseUnitTestCase { metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( TestEntity.class ) .buildMetadata(); + metadata.orderColumns( true ); metadata.validate(); } @@ -77,7 +78,7 @@ public class TableGeneratorTest extends BaseUnitTestCase { isCommandGenerated( commands, expectedTestEntityTableCreationCommand ) ); - final String expectedIdTableGeneratorCreationCommand = "CREATE TABLE ID_TABLE_GENERATOR \\(PK .*, VALUE .*, PRIMARY KEY \\(PK\\)\\);"; + final String expectedIdTableGeneratorCreationCommand = "CREATE TABLE ID_TABLE_GENERATOR \\(VALUE .*, PK .*, PRIMARY KEY \\(PK\\)\\);"; assertTrue( "The command '" + expectedIdTableGeneratorCreationCommand + "' has not been correctly generated", diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/TableGeneratorsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/TableGeneratorsTest.java index a83b0fcb23..2df5b6e0ae 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/TableGeneratorsTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/idgenerator/TableGeneratorsTest.java @@ -61,6 +61,7 @@ public class TableGeneratorsTest extends BaseUnitTestCase { metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( TestEntity.class ) .buildMetadata(); + metadata.orderColumns( true ); metadata.validate(); } @@ -78,7 +79,7 @@ public class TableGeneratorsTest extends BaseUnitTestCase { isCommandGenerated( commands, expectedTestEntityTableCreationCommand ) ); - final String expectedIdTableGeneratorCreationCommand = "CREATE TABLE ID_TABLE_GENERATOR \\(PK .*, VALUE .*, PRIMARY KEY \\(PK\\)\\);"; + final String expectedIdTableGeneratorCreationCommand = "CREATE TABLE ID_TABLE_GENERATOR \\(VALUE .*, PK .*, PRIMARY KEY \\(PK\\)\\);"; assertTrue( "The command '" + expectedIdTableGeneratorCreationCommand + "' has not been correctly generated", diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/inheritance/ForeignKeyNameTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/inheritance/ForeignKeyNameTest.java index df3afed4eb..c78b6cd9dd 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/inheritance/ForeignKeyNameTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/inheritance/ForeignKeyNameTest.java @@ -46,6 +46,7 @@ public class ForeignKeyNameTest extends BaseUnitTestCase { .addResource( "org/hibernate/orm/test/schemaupdate/inheritance/Manager.hbm.xml" ) .addResource( "org/hibernate/orm/test/schemaupdate/inheritance/Payment.hbm.xml" ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() @@ -75,6 +76,7 @@ public class ForeignKeyNameTest extends BaseUnitTestCase { final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addResource( "org/hibernate/orm/test/schemaupdate/inheritance/Payment.hbm.xml" ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaUpdate() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/inheritance/hhh_x/InheritanceSchemaUpdateTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/inheritance/hhh_x/InheritanceSchemaUpdateTest.java index 8dcaa387e9..fb9175fe9a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/inheritance/hhh_x/InheritanceSchemaUpdateTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/inheritance/hhh_x/InheritanceSchemaUpdateTest.java @@ -36,6 +36,7 @@ public class InheritanceSchemaUpdateTest extends BaseUnitTestCase { .addAnnotatedClass( Step.class ) .addAnnotatedClass( GroupStep.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); try { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/inheritance/tableperclass/SchemaCreationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/inheritance/tableperclass/SchemaCreationTest.java index ba0014083e..a8a8d0d9ca 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/inheritance/tableperclass/SchemaCreationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/inheritance/tableperclass/SchemaCreationTest.java @@ -63,6 +63,7 @@ public class SchemaCreationTest { metadataSources.addAnnotatedClass( Element.class ); metadataSources.addAnnotatedClass( Category.class ); metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); final SchemaExport schemaExport = new SchemaExport( ) .setHaltOnError( true ) diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/manytomany/ForeignKeyNameTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/manytomany/ForeignKeyNameTest.java index 1544dcb6ef..6f90976ce3 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/manytomany/ForeignKeyNameTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/manytomany/ForeignKeyNameTest.java @@ -43,6 +43,7 @@ public class ForeignKeyNameTest extends BaseUnitTestCase { final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addResource( "org/hibernate/orm/test/schemaupdate/manytomany/UserGroup.hbm.xml" ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); new SchemaExport() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/uniqueconstraint/UniqueConstraintDropTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/uniqueconstraint/UniqueConstraintDropTest.java index 9e78e070c5..3c92799121 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/uniqueconstraint/UniqueConstraintDropTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/uniqueconstraint/UniqueConstraintDropTest.java @@ -70,6 +70,7 @@ public class UniqueConstraintDropTest { metadata = (MetadataImplementor) new MetadataSources( ssr ) .addResource( "org/hibernate/orm/test/schemaupdate/uniqueconstraint/TestEntity.hbm.xml" ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); tool = (HibernateSchemaManagementTool) ssr.getService( SchemaManagementTool.class ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/uniqueconstraint/UniqueConstraintGenerationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/uniqueconstraint/UniqueConstraintGenerationTest.java index 4d862e0439..df4dd2f73b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/uniqueconstraint/UniqueConstraintGenerationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/uniqueconstraint/UniqueConstraintGenerationTest.java @@ -53,6 +53,7 @@ public class UniqueConstraintGenerationTest { metadata = (MetadataImplementor) new MetadataSources( ssr ) .addResource( "org/hibernate/orm/test/schemaupdate/uniqueconstraint/TestEntity.hbm.xml" ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/EnumValidationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/EnumValidationTest.java index 81c83d020f..6dd7db8f2c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/EnumValidationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/EnumValidationTest.java @@ -79,10 +79,12 @@ public class EnumValidationTest implements ExecutionOptions { oldMetadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( TestEntityOld.class ) .buildMetadata(); + oldMetadata.orderColumns( false ); oldMetadata.validate(); metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( TestEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); try { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/InstantValidationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/InstantValidationTest.java index c2b0a0d1b3..3c9a51f414 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/InstantValidationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/InstantValidationTest.java @@ -76,10 +76,12 @@ public class InstantValidationTest implements ExecutionOptions { oldMetadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( TestEntityOld.class ) .buildMetadata(); + oldMetadata.orderColumns( false ); oldMetadata.validate(); metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( TestEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); try { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/JoinTableWithDefaultSchemaTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/JoinTableWithDefaultSchemaTest.java index 676c855a87..ff443bb8c9 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/JoinTableWithDefaultSchemaTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/JoinTableWithDefaultSchemaTest.java @@ -48,6 +48,7 @@ public class JoinTableWithDefaultSchemaTest extends BaseUnitTestCase { .addAnnotatedClass( Task.class ) .addAnnotatedClass( Project.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); // first create the schema... diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/LongVarcharValidationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/LongVarcharValidationTest.java index 61473b217b..768a62028e 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/LongVarcharValidationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/LongVarcharValidationTest.java @@ -82,6 +82,7 @@ public class LongVarcharValidationTest implements ExecutionOptions { MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( Translation.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/NumericValidationTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/NumericValidationTest.java index eafdba5421..f76f6baa5c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/NumericValidationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemavalidation/NumericValidationTest.java @@ -74,6 +74,7 @@ public class NumericValidationTest implements ExecutionOptions { metadata = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( TestEntity.class ) .buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); try { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/tool/schema/IndividuallySchemaValidatorImplConnectionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/tool/schema/IndividuallySchemaValidatorImplConnectionTest.java index 12cf3ee536..938f4d3a74 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/tool/schema/IndividuallySchemaValidatorImplConnectionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/tool/schema/IndividuallySchemaValidatorImplConnectionTest.java @@ -138,6 +138,7 @@ public class IndividuallySchemaValidatorImplConnectionTest extends BaseUnitTestC metadataSources.addAnnotatedClass( UnqualifiedMissingEntity.class ); MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); Map settings = new HashMap<>( ); @@ -170,6 +171,7 @@ public class IndividuallySchemaValidatorImplConnectionTest extends BaseUnitTestC metadataSources.addAnnotatedClass( UnqualifiedMissingEntity.class ); metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); SchemaValidator schemaValidator = new IndividuallySchemaValidatorImpl( tool, DefaultSchemaFilter.INSTANCE ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/tool/schema/IndividuallySchemaValidatorImplTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/tool/schema/IndividuallySchemaValidatorImplTest.java index 84df7ef7c4..42ade6cdb8 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/tool/schema/IndividuallySchemaValidatorImplTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/tool/schema/IndividuallySchemaValidatorImplTest.java @@ -118,6 +118,7 @@ public class IndividuallySchemaValidatorImplTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( MissingEntity.class ); final MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); try { @@ -135,6 +136,7 @@ public class IndividuallySchemaValidatorImplTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( UnqualifiedMissingEntity.class ); final MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); try { @@ -152,6 +154,7 @@ public class IndividuallySchemaValidatorImplTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( NoNameColumn.class ); MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); Map settings = new HashMap<>( ); @@ -184,6 +187,7 @@ public class IndividuallySchemaValidatorImplTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( NameColumn.class ); metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); try { @@ -207,6 +211,7 @@ public class IndividuallySchemaValidatorImplTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( NameColumn.class ); MetadataImplementor metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); Map settings = new HashMap<>( ); @@ -239,6 +244,7 @@ public class IndividuallySchemaValidatorImplTest extends BaseUnitTestCase { metadataSources.addAnnotatedClass( IntegerNameColumn.class ); metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); try { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/type/OracleLongLobTypeTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/type/OracleLongLobTypeTest.java index c8e18a52ca..68faca45da 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/type/OracleLongLobTypeTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/type/OracleLongLobTypeTest.java @@ -103,6 +103,7 @@ public class OracleLongLobTypeTest extends BaseUnitTestCase { final MetadataImplementor mappings = (MetadataImplementor) new MetadataSources( ssr ) .addAnnotatedClass( entityClass ) .buildMetadata(); + mappings.orderColumns( false ); mappings.validate(); final PersistentClass entityBinding = mappings.getEntityBinding( entityClass.getName() ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/type/SQLServerNVarCharTypeTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/type/SQLServerNVarCharTypeTest.java index 245dc1abc0..fecf7dde17 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/type/SQLServerNVarCharTypeTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/type/SQLServerNVarCharTypeTest.java @@ -61,6 +61,7 @@ public class SQLServerNVarCharTypeTest { metadataSources.addAnnotatedClass( c ); } metadata = (MetadataImplementor) metadataSources.buildMetadata(); + metadata.orderColumns( false ); metadata.validate(); SchemaExport schemaExport = new SchemaExport(); schemaExport.setHaltOnError( true ) diff --git a/hibernate-core/src/test/java17/org/hibernate/orm/test/records/RecordStructEmbeddableTest.java b/hibernate-core/src/test/java17/org/hibernate/orm/test/records/RecordStructEmbeddableTest.java new file mode 100644 index 0000000000..258e4db433 --- /dev/null +++ b/hibernate-core/src/test/java17/org/hibernate/orm/test/records/RecordStructEmbeddableTest.java @@ -0,0 +1,293 @@ +/* + * 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.records; + +import java.util.List; + +import org.hibernate.annotations.Struct; +import org.hibernate.boot.registry.StandardServiceRegistry; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.dialect.DB2Dialect; +import org.hibernate.dialect.OracleDialect; +import org.hibernate.dialect.PostgreSQLDialect; +import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; + +import org.hibernate.testing.orm.junit.BaseSessionFactoryFunctionalTest; +import org.hibernate.testing.orm.junit.RequiresDialect; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import jakarta.persistence.Embeddable; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Tuple; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNull; + +@RequiresDialect( PostgreSQLDialect.class ) +@RequiresDialect( OracleDialect.class ) +@RequiresDialect( DB2Dialect.class ) +public class RecordStructEmbeddableTest extends BaseSessionFactoryFunctionalTest { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + RecordStructHolder.class + }; + } + + @Override + public StandardServiceRegistry produceServiceRegistry(StandardServiceRegistryBuilder ssrBuilder) { + // Make sure this stuff runs on a dedicated connection pool, + // otherwise we might run into ORA-21700: object does not exist or is marked for delete + // because the JDBC connection or database session caches something that should have been invalidated + ssrBuilder.applySetting( AvailableSettings.CONNECTION_PROVIDER, DriverManagerConnectionProviderImpl.class.getName() ); + return super.produceServiceRegistry( ssrBuilder ); + } + + @BeforeEach + public void setUp() { + inTransaction( + session -> { + session.persist( new RecordStructHolder( 1L, Point.createAggregate1() ) ); + session.persist( new RecordStructHolder( 2L, Point.createAggregate2() ) ); + } + ); + } + + @AfterEach + protected void cleanupTest() { + inTransaction( + session -> { + session.createQuery( "delete from RecordStructHolder h" ).executeUpdate(); + } + ); + } + + @Test + public void testUpdate() { + sessionFactoryScope().inTransaction( + entityManager -> { + RecordStructHolder RecordStructHolder = entityManager.find( RecordStructHolder.class, 1L ); + RecordStructHolder.setThePoint( Point.createAggregate2() ); + entityManager.flush(); + entityManager.clear(); + assertStructEquals( Point.createAggregate2(), entityManager.find( RecordStructHolder.class, 1L ).getThePoint() ); + } + ); + } + + @Test + public void testFetch() { + sessionFactoryScope().inSession( + entityManager -> { + List RecordStructHolders = entityManager.createQuery( "from RecordStructHolder b where b.id = 1", RecordStructHolder.class ).getResultList(); + assertEquals( 1, RecordStructHolders.size() ); + assertEquals( 1L, RecordStructHolders.get( 0 ).getId() ); + assertStructEquals( Point.createAggregate1(), RecordStructHolders.get( 0 ).getThePoint() ); + } + ); + } + + @Test + public void testFetchNull() { + sessionFactoryScope().inSession( + entityManager -> { + List RecordStructHolders = entityManager.createQuery( "from RecordStructHolder b where b.id = 2", RecordStructHolder.class ).getResultList(); + assertEquals( 1, RecordStructHolders.size() ); + assertEquals( 2L, RecordStructHolders.get( 0 ).getId() ); + assertStructEquals( Point.createAggregate2(), RecordStructHolders.get( 0 ).getThePoint() ); + } + ); + } + + @Test + public void testDomainResult() { + sessionFactoryScope().inSession( + entityManager -> { + List structs = entityManager.createQuery( "select b.thePoint from RecordStructHolder b where b.id = 1", Point.class ).getResultList(); + assertEquals( 1, structs.size() ); + assertStructEquals( Point.createAggregate1(), structs.get( 0 ) ); + } + ); + } + + @Test + public void testSelectionItems() { + sessionFactoryScope().inSession( + entityManager -> { + List tuples = entityManager.createQuery( + "select " + + "b.thePoint.x," + + "b.thePoint.y," + + "b.thePoint.z " + + "from RecordStructHolder b where b.id = 1", + Tuple.class + ).getResultList(); + assertEquals( 1, tuples.size() ); + final Tuple tuple = tuples.get( 0 ); + assertStructEquals( + Point.createAggregate1(), + new Point( + tuple.get( 1, String.class ), + tuple.get( 0, int.class ), + tuple.get( 2, int.class ) + ) + ); + } + ); + } + + @Test + public void testDeleteWhere() { + sessionFactoryScope().inTransaction( + entityManager -> { + entityManager.createQuery( "delete RecordStructHolder b where b.thePoint is not null" ).executeUpdate(); + assertNull( entityManager.find( RecordStructHolder.class, 1L ) ); + } + ); + } + + @Test + public void testUpdateAggregate() { + sessionFactoryScope().inTransaction( + entityManager -> { + entityManager.createQuery( "update RecordStructHolder b set b.thePoint = null" ).executeUpdate(); + assertNull( entityManager.find( RecordStructHolder.class, 1L ).getThePoint() ); + } + ); + } + + @Test + public void testUpdateAggregateMember() { + sessionFactoryScope().inTransaction( + entityManager -> { + entityManager.createQuery( "update RecordStructHolder b set b.thePoint.x = null" ).executeUpdate(); + Point struct = Point.createAggregate1().withX( null ); + assertStructEquals( struct, entityManager.find( RecordStructHolder.class, 1L ).getThePoint() ); + } + ); + } + + @Test + public void testUpdateMultipleAggregateMembers() { + sessionFactoryScope().inTransaction( + entityManager -> { + entityManager.createQuery( "update RecordStructHolder b set b.thePoint.y = null, b.thePoint.z = null" ).executeUpdate(); + Point struct = Point.createAggregate1().withY( null ).withZ( null ); + assertStructEquals( struct, entityManager.find( RecordStructHolder.class, 1L ).getThePoint() ); + } + ); + } + + @Test + public void testUpdateAllAggregateMembers() { + sessionFactoryScope().inTransaction( + entityManager -> { + Point struct = Point.createAggregate1(); + entityManager.createQuery( + "update RecordStructHolder b set " + + "b.thePoint.x = :x," + + "b.thePoint.y = :y," + + "b.thePoint.z = :z " + + "where b.id = 2" + ) + .setParameter( "x", struct.x() ) + .setParameter( "y", struct.y() ) + .setParameter( "z", struct.z() ) + .executeUpdate(); + assertStructEquals( Point.createAggregate1(), entityManager.find( RecordStructHolder.class, 2L ).getThePoint() ); + } + ); + } + + @Test + public void testNativeQuery() { + sessionFactoryScope().inTransaction( + entityManager -> { + //noinspection unchecked + List resultList = entityManager.createNativeQuery( + "select b.thePoint from RecordStructHolder b where b.id = 1", + // DB2 does not support structs on the driver level, and we instead do a XML serialization/deserialization + // So in order to receive the correct value, we have to specify the actual type that we expect + getDialect() instanceof DB2Dialect + ? (Class) (Class) Point.class + // Using Object.class on purpose to verify Dialect#resolveSqlTypeDescriptor works + : Object.class + ) + .getResultList(); + assertEquals( 1, resultList.size() ); + assertInstanceOf( Point.class, resultList.get( 0 ) ); + Point struct = (Point) resultList.get( 0 ); + assertStructEquals( Point.createAggregate1(), struct ); + } + ); + } + + private void assertStructEquals(Point point1, Point point2) { + assertEquals( point1.x(), point2.x() ); + assertEquals( point1.y(), point2.y() ); + assertEquals( point1.z(), point2.z() ); + } + + @Entity(name = "RecordStructHolder") + public static class RecordStructHolder { + + @Id + private Long id; + @Struct(name = "my_point_type") + private Point thePoint; + + public RecordStructHolder() { + } + + public RecordStructHolder(Long id, Point thePoint) { + this.id = id; + this.thePoint = thePoint; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Point getThePoint() { + return thePoint; + } + + public void setThePoint(Point aggregate) { + this.thePoint = aggregate; + } + + } + + @Embeddable + record Point(String y, Integer x, Integer z) { + public Point withX(Integer x) { + return new Point( y, x, z ); + } + public Point withY(String y) { + return new Point( y, x, z ); + } + public Point withZ(Integer z) { + return new Point( y, x, z ); + } + public static Point createAggregate1() { + return new Point( "1", 10, -100 ); + } + public static Point createAggregate2() { + return new Point( "20", 2, -200 ); + } + } +} diff --git a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/entities/converter/BasicModelingTest.java b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/entities/converter/BasicModelingTest.java index 508b47cd94..dd1640e77f 100644 --- a/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/entities/converter/BasicModelingTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/orm/test/envers/entities/converter/BasicModelingTest.java @@ -8,9 +8,9 @@ package org.hibernate.orm.test.envers.entities.converter; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.internal.MetadataImpl; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.cfg.AvailableSettings; import org.hibernate.orm.test.envers.AbstractEnversTest; import org.hibernate.mapping.PersistentClass; @@ -37,7 +37,8 @@ public class BasicModelingTest extends AbstractEnversTest { .applyAttributeConverter( SexConverter.class ) .build(); - ( (MetadataImpl) metadata ).validate(); + ( (MetadataImplementor) metadata ).orderColumns( false ); + ( (MetadataImplementor) metadata ).validate(); PersistentClass personBinding = metadata.getEntityBinding( Person.class.getName() ); assertNotNull( personBinding ); diff --git a/tooling/hibernate-ant/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java b/tooling/hibernate-ant/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java index a2b937a793..075596ca12 100644 --- a/tooling/hibernate-ant/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java +++ b/tooling/hibernate-ant/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java @@ -265,6 +265,7 @@ public class SchemaExportTask extends MatchingTask { } final MetadataImplementor metadata = (MetadataImplementor) metadataBuilder.build(); + metadata.orderColumns( false ); metadata.validate(); SchemaManagementToolCoordinator.process(