From 5f8bf125fc9c203d7c7259ab3c16b3f5e7f20213 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Sat, 14 Sep 2024 15:21:50 +0200 Subject: [PATCH] HHH-18619 add support for @ForeignKey(options), @UniqueConstraint(options), @Index(options) --- .../boot/model/internal/CollectionBinder.java | 9 ++++ .../boot/model/internal/EntityBinder.java | 5 ++- .../boot/model/internal/IndexBinder.java | 7 +++ .../boot/model/internal/MapBinder.java | 4 +- .../boot/model/internal/ToOneBinder.java | 3 ++ .../java/org/hibernate/dialect/Dialect.java | 14 +++--- .../dialect/DialectDelegateWrapper.java | 4 +- .../org/hibernate/dialect/SpannerDialect.java | 3 +- .../unique/AlterTableUniqueDelegate.java | 8 +++- .../unique/CreateTableUniqueDelegate.java | 2 +- .../java/org/hibernate/mapping/Column.java | 18 +++----- .../org/hibernate/mapping/Constraint.java | 9 ++++ .../hibernate/mapping/DenormalizedTable.java | 2 + .../java/org/hibernate/mapping/Index.java | 13 ++++-- .../java/org/hibernate/mapping/ManyToOne.java | 7 +-- .../org/hibernate/mapping/SimpleValue.java | 12 ++++- .../java/org/hibernate/mapping/Table.java | 16 ++++--- .../java/org/hibernate/mapping/ToOne.java | 7 ++- .../internal/AbstractSchemaMigrator.java | 3 +- .../schema/internal/ColumnDefinitions.java | 4 +- .../schema/internal/SchemaCreatorImpl.java | 13 +++--- .../schema/internal/SchemaDropperImpl.java | 16 ++++--- .../schema/internal/SchemaTruncatorImpl.java | 25 +++++------ .../internal/StandardForeignKeyExporter.java | 8 +++- .../internal/StandardIndexExporter.java | 4 ++ .../internal/StandardSequenceExporter.java | 2 +- .../internal/StandardTableExporter.java | 6 +-- .../internal/StandardUniqueKeyExporter.java | 31 ++++--------- .../schemaupdate/options/OptionsTest.java | 45 +++++++++++++++++++ 29 files changed, 196 insertions(+), 104 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/options/OptionsTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java index 061906a1bb..eba15ceee2 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java @@ -2075,6 +2075,7 @@ public abstract class CollectionBinder { else { key.setForeignKeyName( nullIfEmpty( foreignKey.name() ) ); key.setForeignKeyDefinition( nullIfEmpty( foreignKey.foreignKeyDefinition() ) ); + key.setForeignKeyOptions( foreignKey.options() ); if ( key.getForeignKeyName() == null && key.getForeignKeyDefinition() == null && collectionTableAnn.joinColumns().length == 1 ) { @@ -2082,6 +2083,7 @@ public abstract class CollectionBinder { final ForeignKey nestedForeignKey = joinColumn.foreignKey(); key.setForeignKeyName( nullIfEmpty( nestedForeignKey.name() ) ); key.setForeignKeyDefinition( nullIfEmpty( nestedForeignKey.foreignKeyDefinition() ) ); + key.setForeignKeyOptions( nestedForeignKey.options() ); } } } @@ -2091,6 +2093,7 @@ public abstract class CollectionBinder { final ForeignKey foreignKey = joinTableAnn.foreignKey(); String foreignKeyName = foreignKey.name(); String foreignKeyDefinition = foreignKey.foreignKeyDefinition(); + String foreignKeyOptions = foreignKey.options(); ConstraintMode foreignKeyValue = foreignKey.value(); final JoinColumn[] joinColumnAnnotations = joinTableAnn.joinColumns(); if ( !ArrayHelper.isEmpty( joinColumnAnnotations ) ) { @@ -2099,6 +2102,7 @@ public abstract class CollectionBinder { if ( foreignKeyName.isEmpty() ) { foreignKeyName = joinColumnForeignKey.name(); foreignKeyDefinition = joinColumnForeignKey.foreignKeyDefinition(); + foreignKeyOptions = joinColumnForeignKey.options(); } if ( foreignKeyValue != NO_CONSTRAINT ) { foreignKeyValue = joinColumnForeignKey.value(); @@ -2111,6 +2115,7 @@ public abstract class CollectionBinder { else { key.setForeignKeyName( nullIfEmpty( foreignKeyName ) ); key.setForeignKeyDefinition( nullIfEmpty( foreignKeyDefinition ) ); + key.setForeignKeyOptions( foreignKeyOptions ); } } else { @@ -2155,6 +2160,7 @@ public abstract class CollectionBinder { else { key.setForeignKeyName( nullIfEmpty( foreignKey.name() ) ); key.setForeignKeyDefinition( nullIfEmpty( foreignKey.foreignKeyDefinition() ) ); + key.setForeignKeyOptions( foreignKey.options() ); } } @@ -2425,6 +2431,7 @@ public abstract class CollectionBinder { final ForeignKey inverseForeignKey = joinTableAnn.inverseForeignKey(); String foreignKeyName = inverseForeignKey.name(); String foreignKeyDefinition = inverseForeignKey.foreignKeyDefinition(); + String foreignKeyOptions = inverseForeignKey.options(); final JoinColumn[] inverseJoinColumns = joinTableAnn.inverseJoinColumns(); if ( !ArrayHelper.isEmpty( inverseJoinColumns ) ) { @@ -2433,6 +2440,7 @@ public abstract class CollectionBinder { final ForeignKey inverseJoinColumnForeignKey = joinColumnAnn.foreignKey(); foreignKeyName = inverseJoinColumnForeignKey.name(); foreignKeyDefinition = inverseJoinColumnForeignKey.foreignKeyDefinition(); + foreignKeyOptions = inverseJoinColumnForeignKey.options(); } } @@ -2445,6 +2453,7 @@ public abstract class CollectionBinder { else { element.setForeignKeyName( nullIfEmpty( foreignKeyName ) ); element.setForeignKeyDefinition( nullIfEmpty( foreignKeyDefinition ) ); + element.setForeignKeyOptions( foreignKeyOptions ); } } return element; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java index 08d98cb50c..6916eb1052 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java @@ -54,7 +54,6 @@ import org.hibernate.annotations.Synchronize; import org.hibernate.annotations.TypeBinderType; import org.hibernate.annotations.View; import org.hibernate.binder.TypeBinder; -import org.hibernate.boot.model.IdentifierGeneratorDefinition; import org.hibernate.boot.model.NamedEntityGraphDefinition; import org.hibernate.boot.model.internal.InheritanceState.ElementsToProcess; import org.hibernate.boot.model.naming.EntityNaming; @@ -896,6 +895,7 @@ public class EntityBinder { else if ( foreignKey != null ) { key.setForeignKeyName( nullIfEmpty( foreignKey.name() ) ); key.setForeignKeyDefinition( nullIfEmpty( foreignKey.foreignKeyDefinition() ) ); + key.setForeignKeyOptions( foreignKey.options() ); } else if ( noConstraintByDefault ) { key.disableForeignKey(); @@ -904,11 +904,13 @@ public class EntityBinder { final ForeignKey nestedFk = pkJoinColumns.foreignKey(); key.setForeignKeyName( nullIfEmpty( nestedFk.name() ) ); key.setForeignKeyDefinition( nullIfEmpty( nestedFk.foreignKeyDefinition() ) ); + key.setForeignKeyOptions( nestedFk.options() ); } else if ( pkJoinColumn != null ) { final ForeignKey nestedFk = pkJoinColumn.foreignKey(); key.setForeignKeyName( nullIfEmpty( nestedFk.name() ) ); key.setForeignKeyDefinition( nullIfEmpty( nestedFk.foreignKeyDefinition() ) ); + key.setForeignKeyOptions( nestedFk.options() ); } } } @@ -1987,6 +1989,7 @@ public class EntityBinder { else { key.setForeignKeyName( nullIfEmpty( jpaSecondaryTable.foreignKey().name() ) ); key.setForeignKeyDefinition( nullIfEmpty( jpaSecondaryTable.foreignKey().foreignKeyDefinition() ) ); + key.setForeignKeyOptions( jpaSecondaryTable.foreignKey().options() ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/IndexBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/IndexBinder.java index 045530a39d..f5c253f579 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/IndexBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/IndexBinder.java @@ -160,6 +160,7 @@ class IndexBinder { String[] columnNames, String[] orderings, boolean unique, + String options, Selectable[] columns) { final IndexOrUniqueKeyNameSource source = new IndexOrUniqueKeyNameSource( context, table, columnNames, originalKeyName ); @@ -174,6 +175,7 @@ class IndexBinder { final UniqueKey uniqueKey = table.getOrCreateUniqueKey( keyName ); uniqueKey.setExplicit( true ); uniqueKey.setNameExplicit( nameExplicit ); + uniqueKey.setOptions( options ); for ( int i = 0; i < columns.length; i++ ) { uniqueKey.addColumn( (Column) columns[i], orderings != null ? orderings[i] : null ); } @@ -182,6 +184,7 @@ class IndexBinder { final String keyName = getImplicitNamingStrategy().determineIndexName( source ).render( getDialect() ); final Index index = table.getOrCreateIndex( keyName ); index.setUnique( unique ); + index.setOptions( options ); for ( int i = 0; i < columns.length; i++ ) { index.addColumn( columns[i], orderings != null ? orderings[i] : null ); } @@ -203,6 +206,7 @@ class IndexBinder { initializeColumns( columnExpressions, ordering, parsed ); final String name = index.name(); final boolean unique = index.unique(); + final String options = index.options(); createIndexOrUniqueKey( table, name, @@ -210,6 +214,7 @@ class IndexBinder { columnExpressions, ordering, unique, + options, selectables( table, name, columnExpressions ) ); } @@ -219,6 +224,7 @@ class IndexBinder { for ( UniqueConstraint constraint : constraints ) { final String name = constraint.name(); final String[] columnNames = constraint.columnNames(); + final String options = constraint.options(); createIndexOrUniqueKey( table, name, @@ -226,6 +232,7 @@ class IndexBinder { columnNames, null, true, + options, columns( table, name, columnNames ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/MapBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/MapBinder.java index 778c9d0000..861a159eef 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/MapBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/MapBinder.java @@ -319,6 +319,7 @@ public class MapBinder extends CollectionBinder { else { element.setForeignKeyName( nullIfEmpty( foreignKey.name() ) ); element.setForeignKeyDefinition( nullIfEmpty( foreignKey.foreignKeyDefinition() ) ); + element.setForeignKeyOptions( foreignKey.options() ); } } } @@ -495,8 +496,7 @@ public class MapBinder extends CollectionBinder { private SimpleValue createTargetValue(Table mapKeyTable, SimpleValue sourceValue) { final SimpleValue targetValue; - if ( sourceValue instanceof ManyToOne ) { - final ManyToOne sourceManyToOne = (ManyToOne) sourceValue; + if ( sourceValue instanceof ManyToOne sourceManyToOne ) { final ManyToOne targetManyToOne = new ManyToOne( getBuildingContext(), mapKeyTable); targetManyToOne.setFetchMode( FetchMode.DEFAULT ); targetManyToOne.setLazy( true ); diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ToOneBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ToOneBinder.java index ea4ad79db8..dfe4b98dfb 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ToOneBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/ToOneBinder.java @@ -609,6 +609,7 @@ public class ToOneBinder { else if ( foreignKey != null ) { value.setForeignKeyName( nullIfEmpty( foreignKey.name() ) ); value.setForeignKeyDefinition( nullIfEmpty( foreignKey.foreignKeyDefinition() ) ); + value.setForeignKeyOptions( foreignKey.options() ); } else if ( noConstraintByDefault ) { value.disableForeignKey(); @@ -617,11 +618,13 @@ public class ToOneBinder { final ForeignKey joinColumnsForeignKey = joinColumns.foreignKey(); value.setForeignKeyName( nullIfEmpty( joinColumnsForeignKey.name() ) ); value.setForeignKeyDefinition( nullIfEmpty( joinColumnsForeignKey.foreignKeyDefinition() ) ); + value.setForeignKeyOptions( joinColumnsForeignKey.options() ); } else if ( joinColumn != null ) { final ForeignKey joinColumnForeignKey = joinColumn.foreignKey(); value.setForeignKeyName( nullIfEmpty( joinColumnForeignKey.name() ) ); value.setForeignKeyDefinition( nullIfEmpty( joinColumnForeignKey.foreignKeyDefinition() ) ); + value.setForeignKeyOptions( joinColumnForeignKey.options() ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index 1520d48d65..c5c94647c8 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -112,10 +112,10 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.loader.ast.spi.MultiKeyLoadSizingStrategy; import org.hibernate.mapping.CheckConstraint; import org.hibernate.mapping.Column; -import org.hibernate.mapping.Constraint; import org.hibernate.mapping.ForeignKey; import org.hibernate.mapping.Index; import org.hibernate.mapping.Table; +import org.hibernate.mapping.UniqueKey; import org.hibernate.mapping.UserDefinedType; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; @@ -3274,7 +3274,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun } /** - * Get an {@link Exporter} for {@link UserDefinedType}s, + * Get an {@link Exporter} for {@link UserDefinedType user defined types}, * usually {@link StandardUserDefinedTypeExporter}. */ public Exporter getUserDefinedTypeExporter() { @@ -3282,7 +3282,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun } /** - * Get an {@link Exporter} for {@link Sequence}s, + * Get an {@link Exporter} for {@linkplain Sequence sequences}, * usually {@link StandardSequenceExporter}. */ public Exporter getSequenceExporter() { @@ -3290,7 +3290,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun } /** - * Get an {@link Exporter} for {@link Index}es, + * Get an {@link Exporter} for {@linkplain Index indexes}, * usually {@link StandardIndexExporter}. */ public Exporter getIndexExporter() { @@ -3298,7 +3298,7 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun } /** - * Get an {@link Exporter} for {@link ForeignKey}s, + * Get an {@link Exporter} for {@linkplain ForeignKey foreign key} constraints, * usually {@link StandardForeignKeyExporter}. */ public Exporter getForeignKeyExporter() { @@ -3306,10 +3306,10 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun } /** - * Get an {@link Exporter} for unique key {@link Constraint}s, + * Get an {@link Exporter} for {@linkplain UniqueKey unique key} constraints, * usually {@link StandardUniqueKeyExporter}. */ - public Exporter getUniqueKeyExporter() { + public Exporter getUniqueKeyExporter() { return uniqueKeyExporter; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DialectDelegateWrapper.java b/hibernate-core/src/main/java/org/hibernate/dialect/DialectDelegateWrapper.java index 7d46f2a0d6..42c21aedcb 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DialectDelegateWrapper.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DialectDelegateWrapper.java @@ -49,10 +49,10 @@ import org.hibernate.exception.spi.SQLExceptionConversionDelegate; import org.hibernate.exception.spi.ViolatedConstraintNameExtractor; import org.hibernate.loader.ast.spi.MultiKeyLoadSizingStrategy; import org.hibernate.mapping.Column; -import org.hibernate.mapping.Constraint; import org.hibernate.mapping.ForeignKey; import org.hibernate.mapping.Index; import org.hibernate.mapping.Table; +import org.hibernate.mapping.UniqueKey; import org.hibernate.mapping.UserDefinedType; import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; @@ -866,7 +866,7 @@ public class DialectDelegateWrapper extends Dialect { } @Override - public Exporter getUniqueKeyExporter() { + public Exporter getUniqueKeyExporter() { return wrapped.getUniqueKeyExporter(); } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SpannerDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SpannerDialect.java index 64709dde6b..d390f039f1 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SpannerDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SpannerDialect.java @@ -30,7 +30,6 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.event.spi.EventSource; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.mapping.Column; -import org.hibernate.mapping.Constraint; import org.hibernate.mapping.ForeignKey; import org.hibernate.mapping.Table; import org.hibernate.mapping.UniqueKey; @@ -802,7 +801,7 @@ public class SpannerDialect extends Dialect { } @Override - public Exporter getUniqueKeyExporter() { + public Exporter getUniqueKeyExporter() { return NOOP_EXPORTER; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/unique/AlterTableUniqueDelegate.java b/hibernate-core/src/main/java/org/hibernate/dialect/unique/AlterTableUniqueDelegate.java index 821f7f77cf..fe8cf41b7a 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/unique/AlterTableUniqueDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/unique/AlterTableUniqueDelegate.java @@ -13,6 +13,8 @@ import org.hibernate.mapping.Column; import org.hibernate.mapping.Table; import org.hibernate.mapping.UniqueKey; +import static org.hibernate.internal.util.StringHelper.isNotEmpty; + /** * A {@link UniqueDelegate} which uses {@code alter table} commands to create and drop * the unique constraint. When possible, prefer {@link CreateTableUniqueDelegate}. @@ -68,7 +70,11 @@ public class AlterTableUniqueDelegate implements UniqueDelegate { fragment.append( " " ).append( uniqueKey.getColumnOrderMap().get( column ) ); } } - return fragment.append( ')' ).toString(); + fragment.append( ')' ); + if ( isNotEmpty( uniqueKey.getOptions() ) ) { + fragment.append( " " ).append( uniqueKey.getOptions() ); + } + return fragment.toString(); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/unique/CreateTableUniqueDelegate.java b/hibernate-core/src/main/java/org/hibernate/dialect/unique/CreateTableUniqueDelegate.java index b0e893717a..3840bb1731 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/unique/CreateTableUniqueDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/unique/CreateTableUniqueDelegate.java @@ -76,7 +76,7 @@ public class CreateTableUniqueDelegate extends AlterTableUniqueDelegate { if ( uniqueKey.isNameExplicit() ) { fragment.append( "constraint " ).append( uniqueKey.getName() ).append( " " ); } - fragment.append( uniqueConstraintSql(uniqueKey) ); + fragment.append( uniqueConstraintSql( uniqueKey ) ); } private static boolean isSingleColumnUnique(Table table, UniqueKey uniqueKey) { diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Column.java b/hibernate-core/src/main/java/org/hibernate/mapping/Column.java index c7e19f1af0..1848598a75 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Column.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Column.java @@ -351,8 +351,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn } private static Type getUnderlyingType(Mapping mapping, Type type, int typeIndex) { - if ( type instanceof ComponentType ) { - final ComponentType componentType = (ComponentType) type; + if ( type instanceof ComponentType componentType ) { int cols = 0; for ( Type subtype : componentType.getSubtypes() ) { int columnSpan = subtype.getColumnSpan( mapping ); @@ -363,8 +362,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn } throw new IndexOutOfBoundsException(); } - else if ( type instanceof EntityType ) { - final EntityType entityType = (EntityType) type; + else if ( type instanceof EntityType entityType ) { final Type idType = entityType.getIdentifierOrUniqueKeyType( mapping ); return getUnderlyingType( mapping, idType, typeIndex ); } @@ -454,8 +452,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn if ( type instanceof ComponentType ) { type = getTypeForComponentValue( mapping, type, getTypeIndex() ); } - if ( type instanceof BasicType ) { - final BasicType basicType = (BasicType) type; + if ( type instanceof BasicType basicType ) { if ( isTemporal( basicType.getExpressibleJavaType() ) ) { precisionToUse = getTemporalPrecision(); lengthToUse = null; @@ -510,12 +507,11 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn private Type getTypeForEntityValue(Mapping mapping, Type type, int typeIndex) { int index = 0; - if ( type instanceof EntityType ) { - final EntityType entityType = (EntityType) type; + if ( type instanceof EntityType entityType ) { return getTypeForEntityValue( mapping, entityType.getIdentifierOrUniqueKeyType( mapping ), typeIndex ); } - else if ( type instanceof ComponentType ) { - for ( Type subtype : ((ComponentType) type).getSubtypes() ) { + else if ( type instanceof ComponentType componentType ) { + for ( Type subtype : componentType.getSubtypes() ) { final Type result = getTypeForEntityValue( mapping, subtype, typeIndex - index ); if ( result != null ) { return result; @@ -672,7 +668,7 @@ public class Column implements Selectable, Serializable, Cloneable, ColumnTypeIn @Override public String getWriteExpr() { - return customWrite != null && customWrite.length() > 0 ? customWrite : "?"; + return customWrite != null && !customWrite.isEmpty() ? customWrite : "?"; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Constraint.java b/hibernate-core/src/main/java/org/hibernate/mapping/Constraint.java index c274d5c5b3..113e0b701a 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Constraint.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Constraint.java @@ -24,6 +24,7 @@ public abstract class Constraint implements Exportable, Serializable { private String name; private final ArrayList columns = new ArrayList<>(); private Table table; + private String options = ""; public String getName() { return name; @@ -33,6 +34,14 @@ public abstract class Constraint implements Exportable, Serializable { this.name = name; } + public String getOptions() { + return options; + } + + public void setOptions(String options) { + this.options = options; + } + public void addColumn(Column column) { if ( !columns.contains( column ) ) { columns.add( column ); 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 efcd37f4b3..12a63fcb38 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/DenormalizedTable.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/DenormalizedTable.java @@ -79,6 +79,7 @@ public class DenormalizedTable extends Table { foreignKey.getColumns(), foreignKey.getReferencedEntityName(), foreignKey.getKeyDefinition(), + foreignKey.getOptions(), foreignKey.getReferencedColumns() ); } @@ -88,6 +89,7 @@ public class DenormalizedTable extends Table { final ForeignKey denormalizedForeignKey = new ForeignKey(this); denormalizedForeignKey.setReferencedEntityName( includedTableFk.getReferencedEntityName() ); denormalizedForeignKey.setKeyDefinition( includedTableFk.getKeyDefinition() ); + denormalizedForeignKey.setOptions( includedTableFk.getOptions() ); denormalizedForeignKey.setReferencedTable( includedTableFk.getReferencedTable() ); denormalizedForeignKey.addReferencedColumns( includedTableFk.getReferencedColumns() ); for ( Column keyColumn : includedTableFk.getColumns() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Index.java b/hibernate-core/src/main/java/org/hibernate/mapping/Index.java index 7abb8f0d91..04938359b5 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Index.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Index.java @@ -18,7 +18,6 @@ import org.hibernate.dialect.Dialect; import static java.util.Collections.unmodifiableList; import static java.util.Collections.unmodifiableMap; -import static java.util.stream.Collectors.toUnmodifiableList; import static java.util.stream.Collectors.toUnmodifiableMap; import static org.hibernate.internal.util.StringHelper.isNotEmpty; import static org.hibernate.internal.util.StringHelper.qualify; @@ -35,6 +34,7 @@ public class Index implements Exportable, Serializable { private Identifier name; private Table table; private boolean unique; + private String options = ""; private final java.util.List selectables = new ArrayList<>(); private final java.util.Map selectableOrderMap = new HashMap<>(); @@ -54,6 +54,14 @@ public class Index implements Exportable, Serializable { return unique; } + public String getOptions() { + return options; + } + + public void setOptions(String options) { + this.options = options; + } + public int getColumnSpan() { return selectables.size(); } @@ -71,8 +79,7 @@ public class Index implements Exportable, Serializable { */ @Deprecated(since = "6.3") public java.util.List getColumns() { - return selectables.stream() - .map( s -> (Column) s ).collect( toUnmodifiableList() ); + return selectables.stream().map( s -> (Column) s ).toList(); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/ManyToOne.java b/hibernate-core/src/main/java/org/hibernate/mapping/ManyToOne.java index e56392b3e6..98b4bb14d6 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/ManyToOne.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/ManyToOne.java @@ -24,7 +24,7 @@ public class ManyToOne extends ToOne { private boolean isLogicalOneToOne; private NotFoundAction notFoundAction; - private Type resolvedType; + private transient Type resolvedType; public ManyToOne(MetadataBuildingContext buildingContext, Table table) { super( buildingContext, table ); @@ -95,8 +95,8 @@ public class ManyToOne extends ToOne { } else { // Make sure synthetic properties are sorted - if ( property.getValue() instanceof Component ) { - ( (Component) property.getValue() ).sortProperties(); + if ( property.getValue() instanceof Component component ) { + component.sortProperties(); } // todo : if "none" another option is to create the ForeignKey object still but to set its #disableCreation flag if ( isForeignKeyEnabled() && !hasFormula() ) { @@ -105,6 +105,7 @@ public class ManyToOne extends ToOne { getConstraintColumns(), ( (EntityType) getType() ).getAssociatedEntityName(), getForeignKeyDefinition(), + getForeignKeyOptions(), new ArrayList<>( property.getColumns() ) ); foreignKey.setReferencedTable( property.getValue().getTable() ); diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java index 45f59ad949..cf1da6fcb8 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java @@ -96,6 +96,7 @@ public abstract class SimpleValue implements KeyValue { private Table table; private String foreignKeyName; private String foreignKeyDefinition; + private String foreignKeyOptions; private boolean alternateUniqueKey; private OnDeleteAction onDeleteAction; private boolean foreignKeyEnabled = true; @@ -347,7 +348,8 @@ public abstract class SimpleValue implements KeyValue { getForeignKeyName(), getConstraintColumns(), entityName, - getForeignKeyDefinition() + getForeignKeyDefinition(), + getForeignKeyOptions() ); foreignKey.setOnDeleteAction( onDeleteAction ); return foreignKey; @@ -443,6 +445,14 @@ public abstract class SimpleValue implements KeyValue { return isForeignKeyEnabled() && !hasFormula(); } + public String getForeignKeyOptions() { + return foreignKeyOptions; + } + + public void setForeignKeyOptions(String foreignKeyOptions) { + this.foreignKeyOptions = foreignKeyOptions; + } + public String getForeignKeyDefinition() { return foreignKeyDefinition; } 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 714d2e1f61..580516e849 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Table.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Table.java @@ -576,8 +576,13 @@ public class Table implements Serializable, ContributableDatabaseObject { public void createForeignKeys(MetadataBuildingContext context) { } + @Deprecated(since="7.0", forRemoval = true) public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName, String keyDefinition) { - return createForeignKey( keyName, keyColumns, referencedEntityName, keyDefinition, null ); + return createForeignKey( keyName, keyColumns, referencedEntityName, keyDefinition, null, null ); + } + + public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName, String keyDefinition, String options) { + return createForeignKey( keyName, keyColumns, referencedEntityName, keyDefinition, options, null ); } public ForeignKey createForeignKey( @@ -585,6 +590,7 @@ public class Table implements Serializable, ContributableDatabaseObject { List keyColumns, String referencedEntityName, String keyDefinition, + String options, List referencedColumns) { final ForeignKeyKey key = new ForeignKeyKey( keyColumns, referencedEntityName, referencedColumns ); @@ -593,6 +599,7 @@ public class Table implements Serializable, ContributableDatabaseObject { foreignKey = new ForeignKey( this ); foreignKey.setReferencedEntityName( referencedEntityName ); foreignKey.setKeyDefinition( keyDefinition ); + foreignKey.setOptions( options ); for ( Column keyColumn : keyColumns ) { foreignKey.addColumn( keyColumn ); } @@ -773,12 +780,11 @@ public class Table implements Serializable, ContributableDatabaseObject { } public boolean equals(Object other) { - if ( !( other instanceof ForeignKeyKey ) ) { + if ( !(other instanceof ForeignKeyKey foreignKeyKey) ) { return false; } - ForeignKeyKey fkk = (ForeignKeyKey) other; - return Arrays.equals( fkk.columns, columns ) - && Arrays.equals( fkk.referencedColumns, referencedColumns ); + return Arrays.equals( foreignKeyKey.columns, columns ) + && Arrays.equals( foreignKeyKey.referencedColumns, referencedColumns ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/ToOne.java b/hibernate-core/src/main/java/org/hibernate/mapping/ToOne.java index 8361460b6d..486587016c 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/ToOne.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/ToOne.java @@ -175,8 +175,7 @@ public abstract class ToOne extends SimpleValue implements Fetchable, SortableVa final Value value = referencedPropertyName == null ? entityBinding.getIdentifier() : entityBinding.getRecursiveProperty( referencedPropertyName ).getValue(); - if ( value instanceof Component ) { - final Component component = (Component) value; + if ( value instanceof Component component ) { final int[] originalPropertyOrder = component.sortProperties(); if ( !sorted ) { if ( originalPropertyOrder != null ) { @@ -201,15 +200,15 @@ public abstract class ToOne extends SimpleValue implements Fetchable, SortableVa if ( isConstrained() ) { final AnnotatedJoinColumn firstColumn = joinColumns.getJoinColumns().get(0); final Object owner = findReferencedColumnOwner( referencedEntity, firstColumn, getBuildingContext() ); - if ( owner instanceof Join ) { + if ( owner instanceof Join join ) { // Here we handle the case of a foreign key that refers to the // primary key of a secondary table of the referenced entity - final Join join = (Join) owner; final ForeignKey foreignKey = getTable().createForeignKey( getForeignKeyName(), getConstraintColumns(), referencedEntity.getEntityName(), getForeignKeyDefinition(), + getForeignKeyOptions(), join.getKey().getColumns() ); foreignKey.setOnDeleteAction( getOnDeleteAction() ); diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/AbstractSchemaMigrator.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/AbstractSchemaMigrator.java index 3230f861b6..62207d5efa 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/AbstractSchemaMigrator.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/AbstractSchemaMigrator.java @@ -28,7 +28,6 @@ import org.hibernate.engine.jdbc.internal.FormatStyle; import org.hibernate.engine.jdbc.internal.Formatter; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.CollectionHelper; -import org.hibernate.mapping.Constraint; import org.hibernate.mapping.ForeignKey; import org.hibernate.mapping.Index; import org.hibernate.mapping.Table; @@ -388,7 +387,7 @@ public abstract class AbstractSchemaMigrator implements SchemaMigrator { } if ( uniqueConstraintStrategy != SKIP ) { - final Exporter exporter = dialect.getUniqueKeyExporter(); + final Exporter exporter = dialect.getUniqueKeyExporter(); for ( UniqueKey uniqueKey : table.getUniqueKeys().values() ) { // Skip if index already exists. Most of the time, this // won't work since most Dialects use Constraints. However, diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ColumnDefinitions.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ColumnDefinitions.java index 13e1084652..3b4d608c21 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ColumnDefinitions.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/ColumnDefinitions.java @@ -11,7 +11,6 @@ import org.hibernate.boot.Metadata; import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.Size; -import org.hibernate.internal.util.StringHelper; import org.hibernate.mapping.CheckConstraint; import org.hibernate.mapping.Column; import org.hibernate.mapping.Table; @@ -27,6 +26,7 @@ import java.util.Comparator; import java.util.List; import java.util.Locale; +import static org.hibernate.internal.util.StringHelper.isNotEmpty; import static org.hibernate.type.SqlTypes.isNumericOrDecimal; import static org.hibernate.type.SqlTypes.isStringType; @@ -122,7 +122,7 @@ class ColumnDefinitions { private static void appendOptions(StringBuilder statement, Column column, Dialect dialect) { final String options = column.getOptions(); - if ( StringHelper.isNotEmpty( options ) ) { + if ( isNotEmpty( options ) ) { statement.append( " " ).append( options ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaCreatorImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaCreatorImpl.java index 06258d30fe..99a1f5ea2a 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaCreatorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaCreatorImpl.java @@ -96,13 +96,14 @@ public class SchemaCreatorImpl implements SchemaCreator { } public SchemaCreatorImpl(ServiceRegistry serviceRegistry, SchemaFilter schemaFilter) { - SchemaManagementTool smt = serviceRegistry.getService( SchemaManagementTool.class ); - if ( !(smt instanceof HibernateSchemaManagementTool) ) { - smt = new HibernateSchemaManagementTool(); - ( (HibernateSchemaManagementTool) smt ).injectServices( (ServiceRegistryImplementor) serviceRegistry ); + if ( serviceRegistry.getService( SchemaManagementTool.class ) + instanceof HibernateSchemaManagementTool schemaManagementTool ) { + tool = schemaManagementTool; + } + else { + tool = new HibernateSchemaManagementTool(); + tool.injectServices( (ServiceRegistryImplementor) serviceRegistry ); } - - this.tool = (HibernateSchemaManagementTool) smt; this.schemaFilter = schemaFilter; } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaDropperImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaDropperImpl.java index 2f1455d15d..4dce97ea74 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaDropperImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaDropperImpl.java @@ -93,13 +93,14 @@ public class SchemaDropperImpl implements SchemaDropper { } public SchemaDropperImpl(ServiceRegistry serviceRegistry, SchemaFilter schemaFilter) { - SchemaManagementTool smt = serviceRegistry.getService( SchemaManagementTool.class ); - if ( !(smt instanceof HibernateSchemaManagementTool) ) { - smt = new HibernateSchemaManagementTool(); - ( (HibernateSchemaManagementTool) smt ).injectServices( (ServiceRegistryImplementor) serviceRegistry ); + if ( serviceRegistry.getService( SchemaManagementTool.class ) + instanceof HibernateSchemaManagementTool schemaManagementTool ) { + tool = schemaManagementTool; + } + else { + tool = new HibernateSchemaManagementTool(); + tool.injectServices( (ServiceRegistryImplementor) serviceRegistry ); } - - this.tool = (HibernateSchemaManagementTool) smt; this.schemaFilter = schemaFilter; } @@ -401,7 +402,8 @@ public class SchemaDropperImpl implements SchemaDropper { GenerationTarget[] targets) { for ( Namespace namespace : metadata.getDatabase().getNamespaces() ) { if ( schemaFilter.includeNamespace( namespace ) ) { - final List dependencyOrderedUserDefinedTypes = namespace.getDependencyOrderedUserDefinedTypes(); + final List dependencyOrderedUserDefinedTypes = + namespace.getDependencyOrderedUserDefinedTypes(); Collections.reverse( dependencyOrderedUserDefinedTypes ); for ( UserDefinedType userDefinedType : dependencyOrderedUserDefinedTypes ) { applySqlStrings( diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaTruncatorImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaTruncatorImpl.java index 2ac9252e93..1b84ba6e5f 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaTruncatorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaTruncatorImpl.java @@ -39,6 +39,7 @@ import org.jboss.logging.Logger; import java.net.URL; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Set; import static org.hibernate.cfg.AvailableSettings.HBM2DDL_CHARSET_NAME; @@ -73,9 +74,11 @@ public class SchemaTruncatorImpl implements SchemaTruncator { ContributableMatcher contributableInclusionFilter, TargetDescriptor targetDescriptor) { - final JdbcContext jdbcContext = tool.resolveJdbcContext( options.getConfigurationValues() ); - final GenerationTarget[] targets = tool.buildGenerationTargets( targetDescriptor, jdbcContext, options.getConfigurationValues(), - true ); //we need autocommit on for DB2 at least + final Map configurationValues = options.getConfigurationValues(); + final JdbcContext jdbcContext = tool.resolveJdbcContext(configurationValues); + final GenerationTarget[] targets = + tool.buildGenerationTargets( targetDescriptor, jdbcContext, configurationValues, + true ); //we need autocommit on for DB2 at least doTruncate( metadata, options, contributableInclusionFilter, jdbcContext.getDialect(), targets ); } @@ -211,9 +214,7 @@ public class SchemaTruncatorImpl implements SchemaTruncator { for ( ForeignKey foreignKey : table.getForeignKeys().values() ) { if ( dialect.canDisableConstraints() ) { applySqlString( - dialect.getTableCleaner().getSqlDisableConstraintString( foreignKey, metadata, - context - ), + dialect.getTableCleaner().getSqlDisableConstraintString( foreignKey, metadata, context ), formatter, options, targets @@ -221,9 +222,7 @@ public class SchemaTruncatorImpl implements SchemaTruncator { } else if ( !dialect.canBatchTruncate() ) { applySqlStrings( - dialect.getForeignKeyExporter().getSqlDropStrings( foreignKey, metadata, - context - ), + dialect.getForeignKeyExporter().getSqlDropStrings( foreignKey, metadata, context ), formatter, options, targets @@ -258,9 +257,7 @@ public class SchemaTruncatorImpl implements SchemaTruncator { for ( ForeignKey foreignKey : table.getForeignKeys().values() ) { if ( dialect.canDisableConstraints() ) { applySqlString( - dialect.getTableCleaner().getSqlEnableConstraintString( foreignKey, metadata, - context - ), + dialect.getTableCleaner().getSqlEnableConstraintString( foreignKey, metadata, context ), formatter, options, targets @@ -268,9 +265,7 @@ public class SchemaTruncatorImpl implements SchemaTruncator { } else if ( !dialect.canBatchTruncate() ) { applySqlStrings( - dialect.getForeignKeyExporter().getSqlCreateStrings( foreignKey, metadata, - context - ), + dialect.getForeignKeyExporter().getSqlCreateStrings( foreignKey, metadata, context ), formatter, options, targets diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardForeignKeyExporter.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardForeignKeyExporter.java index 814618ffc0..d9988f8717 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardForeignKeyExporter.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardForeignKeyExporter.java @@ -18,6 +18,8 @@ import org.hibernate.mapping.Column; import org.hibernate.mapping.ForeignKey; import org.hibernate.tool.schema.spi.Exporter; +import static org.hibernate.internal.util.StringHelper.isNotEmpty; + /** * An {@link Exporter} for {@linkplain ForeignKey foreign key constraints}. * @@ -78,12 +80,16 @@ public class StandardForeignKeyExporter implements Exporter { ); if ( dialect.supportsCascadeDelete() ) { - OnDeleteAction onDeleteAction = foreignKey.getOnDeleteAction(); + final OnDeleteAction onDeleteAction = foreignKey.getOnDeleteAction(); if ( onDeleteAction != null && onDeleteAction != OnDeleteAction.NO_ACTION ) { buffer.append( " on delete " ).append( onDeleteAction.toSqlString() ); } } + if ( isNotEmpty( foreignKey.getOptions() ) ) { + buffer.append( " " ).append( foreignKey.getOptions() ); + } + return new String[] { buffer.toString() }; } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardIndexExporter.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardIndexExporter.java index a709c20fd2..adf42ac985 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardIndexExporter.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardIndexExporter.java @@ -17,6 +17,7 @@ import org.hibernate.mapping.Index; import org.hibernate.mapping.Selectable; import org.hibernate.tool.schema.spi.Exporter; +import static org.hibernate.internal.util.StringHelper.isNotEmpty; import static org.hibernate.internal.util.StringHelper.qualify; /** @@ -47,6 +48,9 @@ public class StandardIndexExporter implements Exporter { .append( " (" ); appendColumnList( index, createIndex ); createIndex.append( ")" ); + if ( isNotEmpty( index.getOptions() ) ) { + createIndex.append( " " ).append( index.getOptions() ); + } return new String[] { createIndex.toString() }; } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardSequenceExporter.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardSequenceExporter.java index c72f710ce4..f60dbcb20d 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardSequenceExporter.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardSequenceExporter.java @@ -14,7 +14,7 @@ import org.hibernate.dialect.Dialect; import org.hibernate.tool.schema.spi.Exporter; /** - * An {@link Exporter} for {@link Sequence sequences}. + * An {@link Exporter} for {@linkplain Sequence sequences}. * * @author Steve Ebersole */ diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardTableExporter.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardTableExporter.java index e1b41241e3..0f1ed37263 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardTableExporter.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardTableExporter.java @@ -186,8 +186,7 @@ public class StandardTableExporter implements Exporter { final AggregateSupport aggregateSupport = dialect.getAggregateSupport(); if ( aggregateSupport != null && aggregateSupport.supportsComponentCheckConstraints() ) { for ( Column column : table.getColumns() ) { - if ( column instanceof AggregateColumn ) { - final AggregateColumn aggregateColumn = (AggregateColumn) column; + if ( column instanceof AggregateColumn aggregateColumn ) { if ( !isArray( aggregateColumn ) ) { applyAggregateColumnCheck( buf, aggregateColumn ); } @@ -241,8 +240,7 @@ public class StandardTableExporter implements Exporter
{ String aggregatePath, AggregateSupport aggregateSupport, Value value) { - if ( value instanceof Component ) { - final Component component = (Component) value; + if ( value instanceof Component component ) { final AggregateColumn subAggregateColumn = component.getAggregateColumn(); if ( subAggregateColumn != null && !isArray( subAggregateColumn ) ) { final String subAggregatePath = subAggregateColumn.getAggregateReadExpressionTemplate( dialect ) diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardUniqueKeyExporter.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardUniqueKeyExporter.java index ba7b65349a..989e6fca14 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardUniqueKeyExporter.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/StandardUniqueKeyExporter.java @@ -9,18 +9,15 @@ package org.hibernate.tool.schema.internal; import org.hibernate.boot.Metadata; import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.dialect.Dialect; -import org.hibernate.mapping.Constraint; import org.hibernate.mapping.UniqueKey; import org.hibernate.tool.schema.spi.Exporter; /** - * An {@link Exporter} for {@link UniqueKey unique constraints}. The type argument is - * {@link Constraint}, rather than {@link UniqueKey}, allowing for {@link Dialect}s - * which create unique constraints for unique indexes. + * An {@link Exporter} for {@linkplain UniqueKey unique constraints}. * * @author Brett Meyer */ -public class StandardUniqueKeyExporter implements Exporter { +public class StandardUniqueKeyExporter implements Exporter { private final Dialect dialect; public StandardUniqueKeyExporter(Dialect dialect) { @@ -28,26 +25,14 @@ public class StandardUniqueKeyExporter implements Exporter { } @Override - public String[] getSqlCreateStrings(Constraint constraint, Metadata metadata, - SqlStringGenerationContext context) { - return new String[] { - dialect.getUniqueDelegate().getAlterTableToAddUniqueKeyCommand( - (UniqueKey) constraint, - metadata, - context - ) - }; + public String[] getSqlCreateStrings(UniqueKey constraint, Metadata metadata, SqlStringGenerationContext context) { + return new String[] { dialect.getUniqueDelegate() + .getAlterTableToAddUniqueKeyCommand( constraint, metadata, context ) }; } @Override - public String[] getSqlDropStrings(Constraint constraint, Metadata metadata, - SqlStringGenerationContext context) { - return new String[] { - dialect.getUniqueDelegate().getAlterTableToDropUniqueKeyCommand( - (UniqueKey) constraint, - metadata, - context - ) - }; + public String[] getSqlDropStrings(UniqueKey constraint, Metadata metadata, SqlStringGenerationContext context) { + return new String[] { dialect.getUniqueDelegate() + .getAlterTableToDropUniqueKeyCommand( constraint, metadata, context ) }; } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/options/OptionsTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/options/OptionsTest.java new file mode 100644 index 0000000000..fb3f7385d0 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/schemaupdate/options/OptionsTest.java @@ -0,0 +1,45 @@ +package org.hibernate.orm.test.schemaupdate.options; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.ForeignKey; +import jakarta.persistence.Id; +import jakarta.persistence.Index; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.SchemaManager; +import jakarta.persistence.SchemaValidationException; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; +import org.hibernate.dialect.PostgreSQLDialect; +import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; +import org.hibernate.testing.orm.junit.Jpa; +import org.hibernate.testing.orm.junit.RequiresDialect; +import org.junit.jupiter.api.Test; + +@Jpa(annotatedClasses = OptionsTest.WithOptions.class, + useCollectingStatementInspector = true) +@RequiresDialect(PostgreSQLDialect.class) +public class OptionsTest { + @Test void test(EntityManagerFactoryScope scope) throws SchemaValidationException { + SchemaManager schemaManager = scope.getEntityManagerFactory().getSchemaManager(); + schemaManager.drop(true); + schemaManager.create(true); + schemaManager.validate(); + } + @Entity + @Table(name = "TableWithOptions", + indexes = @Index(columnList = "name", options = "nulls distinct"), + uniqueConstraints = @UniqueConstraint(columnNames = "name", options = "deferrable")) + static class WithOptions { + @Id + long id; + + @Column(name = "name", options = "compression pglz") + String name; + + @ManyToOne + @JoinColumn(foreignKey = @ForeignKey(name = "ToOther", options = "match full")) + WithOptions other; + } +}