diff --git a/hibernate-core/src/main/java/org/hibernate/LockOptions.java b/hibernate-core/src/main/java/org/hibernate/LockOptions.java index 98c71c47c9f4..36926ebedbf0 100644 --- a/hibernate-core/src/main/java/org/hibernate/LockOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/LockOptions.java @@ -163,7 +163,6 @@ public class LockOptions implements Serializable { private PessimisticLockScope pessimisticLockScope; private Boolean followOnLocking; - private Map aliasSpecificLockModes; /** @@ -510,8 +509,6 @@ public int hashCode() { return Objects.hash( lockMode, timeout, aliasSpecificLockModes, followOnLocking, pessimisticLockScope ); } - - /** * Set of {@link Map.Entry}s, each associating an alias with its * specified {@linkplain #setAliasSpecificLockMode alias-specific} diff --git a/hibernate-core/src/main/java/org/hibernate/boot/SchemaAutoTooling.java b/hibernate-core/src/main/java/org/hibernate/boot/SchemaAutoTooling.java index 66e31e7defec..f81c133f6cb0 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/SchemaAutoTooling.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/SchemaAutoTooling.java @@ -13,8 +13,11 @@ * Defines the possible values for {@value AvailableSettings#HBM2DDL_AUTO}. * * @deprecated This enumeration is currently unused and will be removed. + * Use {@link org.hibernate.tool.schema.Action} instead. * * @author Steve Ebersole + * + * @see org.hibernate.tool.schema.Action */ @Deprecated(since = "7.0", forRemoval = true) public enum SchemaAutoTooling { 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 2aedcaf849fd..4af6c2b31045 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 @@ -6,7 +6,6 @@ import java.io.Serializable; import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -62,10 +61,11 @@ import org.hibernate.query.sqm.function.SqmFunctionRegistry; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.tool.schema.Action; -import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator; +import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.ActionGrouping; import org.hibernate.type.spi.TypeConfiguration; import static java.lang.String.join; +import static java.util.Collections.emptySet; import static org.hibernate.cfg.AvailableSettings.EVENT_LISTENER_PREFIX; import static org.hibernate.internal.util.StringHelper.splitAtCommas; import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize; @@ -164,10 +164,10 @@ public SqmFunctionRegistry getFunctionRegistry() { @Override public SessionFactoryBuilder getSessionFactoryBuilder() { - final SessionFactoryBuilderImplementor defaultBuilder = getFactoryBuilder(); + final var defaultBuilder = getFactoryBuilder(); SessionFactoryBuilder builder = null; List activeFactoryNames = null; - for ( SessionFactoryBuilderFactory discoveredBuilderFactory : getSessionFactoryBuilderFactories() ) { + for ( var discoveredBuilderFactory : getSessionFactoryBuilderFactories() ) { final SessionFactoryBuilder returnedBuilder = discoveredBuilderFactory.getSessionFactoryBuilder( this, defaultBuilder ); if ( returnedBuilder != null ) { @@ -371,85 +371,90 @@ public NamedObjectRepository buildNamedQueryRepository() { @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; + // No need to order columns when using the no-op strategy + if ( columnOrderingStrategy != ColumnOrderingStrategyLegacy.INSTANCE ) { + final boolean shouldOrderTableColumns = forceOrdering || shouldOrderTableColumns(); + for ( Namespace namespace : database.getNamespaces() ) { + if ( shouldOrderTableColumns ) { + for ( Table table : namespace.getTables() ) { + handleTable( table, columnOrderingStrategy ); + handlePrimaryKey( table, columnOrderingStrategy ); + handleForeignKeys( table, columnOrderingStrategy ); + } + } + for ( UserDefinedType userDefinedType : namespace.getUserDefinedTypes() ) { + handleUDT( userDefinedType, columnOrderingStrategy ); + } + } } + } - final boolean shouldOrderTableColumns = forceOrdering || shouldOrderTableColumns(); + private void handleTable(Table table, ColumnOrderingStrategy columnOrderingStrategy) { + final List tableColumns = columnOrderingStrategy.orderTableColumns( table, this ); + if ( tableColumns != null ) { + table.reorderColumns( tableColumns ); + } + } - 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 - ); + private void handleUDT(UserDefinedType userDefinedType, ColumnOrderingStrategy columnOrderingStrategy) { + if ( userDefinedType instanceof UserDefinedObjectType objectType + && objectType.getColumns().size() > 1 ) { + final List objectTypeColumns = + columnOrderingStrategy.orderUserDefinedTypeColumns( objectType, this ); + if ( objectTypeColumns != null ) { + objectType.reorderColumns( objectTypeColumns ); + } + } + } + + private void handleForeignKeys(Table table, ColumnOrderingStrategy columnOrderingStrategy) { + for ( ForeignKey foreignKey : table.getForeignKeys().values() ) { + final List columns = foreignKey.getColumns(); + if ( columns.size() > 1 ) { + if ( foreignKey.getReferencedColumns().isEmpty() ) { + final PrimaryKey targetPrimaryKey = + foreignKey.getReferencedTable().getPrimaryKey(); + // Make sure we order the columns of the primary key first, + // so that foreign key ordering can rely on this + if ( targetPrimaryKey.getOriginalOrder() == null ) { + final List primaryKeyColumns = + columnOrderingStrategy.orderConstraintColumns( targetPrimaryKey, this ); if ( primaryKeyColumns != null ) { - primaryKey.reorderColumns( primaryKeyColumns ); + targetPrimaryKey.reorderColumns( primaryKeyColumns ); } } - 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] ) ); - } - } - } + + // Patch up the order of foreign keys based on new order of the target primary key + final int[] originalPrimaryKeyOrder = targetPrimaryKey.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 instanceof UserDefinedObjectType objectType - && objectType.getColumns().size() > 1 ) { - final List objectTypeColumns = - columnOrderingStrategy.orderUserDefinedTypeColumns( objectType, this ); - if ( objectTypeColumns != null ) { - objectType.reorderColumns( objectTypeColumns ); - } - } + } + } + + private void handlePrimaryKey(Table table, ColumnOrderingStrategy columnOrderingStrategy) { + 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 ); } } } private boolean shouldOrderTableColumns() { - final ConfigurationService configurationService = - metadataBuildingOptions.getServiceRegistry().requireService( ConfigurationService.class ); - final Set groupings = - SchemaManagementToolCoordinator.ActionGrouping.interpret( this, - configurationService.getSettings() ); - if ( groupings.isEmpty() ) { - return false; - } - for ( SchemaManagementToolCoordinator.ActionGrouping grouping : groupings ) { + final var settings = + metadataBuildingOptions.getServiceRegistry() + .requireService( ConfigurationService.class ) + .getSettings(); + for ( ActionGrouping grouping : ActionGrouping.interpret( this, settings ) ) { if ( isColumnOrderingRelevant( grouping.getScriptAction() ) || isColumnOrderingRelevant( grouping.getDatabaseAction() ) ) { return true; @@ -479,30 +484,29 @@ public void validate() throws MappingException { @Override public Set getMappedSuperclassMappingsCopy() { return mappedSuperclassMap == null - ? Collections.emptySet() + ? emptySet() : new HashSet<>( mappedSuperclassMap.values() ); } @Override public void initSessionFactory(SessionFactoryImplementor sessionFactory) { // must not use BootstrapContext services here - final ServiceRegistryImplementor sessionFactoryServiceRegistry = sessionFactory.getServiceRegistry(); - assert sessionFactoryServiceRegistry != null; + final ServiceRegistryImplementor registry = sessionFactory.getServiceRegistry(); + assert registry != null; final ConfigurationService configurationService = - sessionFactoryServiceRegistry.requireService( ConfigurationService.class ); + registry.requireService( ConfigurationService.class ); final ClassLoaderService classLoaderService = - sessionFactoryServiceRegistry.requireService( ClassLoaderService.class ); + registry.requireService( ClassLoaderService.class ); final EventListenerRegistry eventListenerRegistry = - sessionFactoryServiceRegistry.requireService( EventListenerRegistry.class ); - for ( Map.Entry entry : configurationService.getSettings().entrySet() ) { - final String propertyName = entry.getKey(); + registry.requireService( EventListenerRegistry.class ); + configurationService.getSettings().forEach( (propertyName, value) -> { if ( propertyName.startsWith( EVENT_LISTENER_PREFIX ) ) { final String eventTypeName = propertyName.substring( EVENT_LISTENER_PREFIX.length() + 1 ); final EventType eventType = EventType.resolveEventTypeByName( eventTypeName ); - final String listeners = (String) entry.getValue(); + final String listeners = (String) value; appendListeners( eventListenerRegistry, classLoaderService, listeners, eventType ); } - } + } ); } private void appendListeners( diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/NavigableRole.java b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/NavigableRole.java index 60becf973ea5..51b1f0848042 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/NavigableRole.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/NavigableRole.java @@ -5,12 +5,14 @@ package org.hibernate.metamodel.model.domain; import java.io.Serializable; +import java.util.Objects; import org.hibernate.Incubating; -import org.hibernate.internal.util.StringHelper; import org.hibernate.spi.DotIdentifierSequence; import org.hibernate.spi.NavigablePath; +import static org.hibernate.internal.util.StringHelper.isEmpty; + /** * A compound path which represents a {@link org.hibernate.metamodel.mapping.ModelPart} * and uniquely identifies it with the runtime metamodel. @@ -41,29 +43,26 @@ public NavigableRole(NavigableRole parent, String localName) { public NavigableRole(NavigableRole parent, String localName, char separator) { this.parent = parent; this.localName = localName; + this.fullPath = fullPath( parent, localName, separator ); + } + private String fullPath(NavigableRole parent, String localName, char separator) { // the _identifierMapper is a "hidden" property on entities with composite keys. // concatenating it will prevent the path from correctly being used to look up // various things such as criteria paths and fetch profile association paths if ( IDENTIFIER_MAPPER_PROPERTY.equals( localName ) ) { - this.fullPath = parent != null ? parent.getFullPath() : ""; + return parent == null ? "" : parent.getFullPath(); } else { final String prefix; if ( parent != null ) { final String resolvedParent = parent.getFullPath(); - if ( StringHelper.isEmpty( resolvedParent ) ) { - prefix = ""; - } - else { - prefix = resolvedParent + separator; - } + prefix = isEmpty( resolvedParent ) ? "" : resolvedParent + separator; } else { prefix = ""; } - - this.fullPath = prefix + localName; + return prefix + localName; } } @@ -80,10 +79,10 @@ public NavigableRole append(String name) { } /** - * Uses `#` as the separator rather than `.`. The intention being that the incoming name is a - * {@link org.hibernate.metamodel.mapping.ModelPartContainer} of some sort - * - * todo (6.0) : better name? + * Uses {@code #} as the separator rather than a period, + * the intention being that the incoming name is a + * {@link org.hibernate.metamodel.mapping.ModelPartContainer} + * of some sort. */ public NavigableRole appendContainer(String name) { return new NavigableRole( this, name, '#' ); @@ -112,20 +111,21 @@ public String toString() { } @Override - public boolean equals(final Object o) { - if ( this == o ) { + public boolean equals(final Object object) { + if ( this == object ) { return true; } - if ( o == null || NavigableRole.class != o.getClass() ) { + else if ( !(object instanceof NavigableRole that) ) { return false; } - NavigableRole that = (NavigableRole) o; - return fullPath.equals( that.fullPath ); + else { + return Objects.equals( this.fullPath, that.fullPath ); + } } @Override public int hashCode() { - return this.fullPath.hashCode(); + return fullPath.hashCode(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/spi/NavigablePath.java b/hibernate-core/src/main/java/org/hibernate/spi/NavigablePath.java index 66a3f5fb730d..e3f9cbb9386a 100644 --- a/hibernate-core/src/main/java/org/hibernate/spi/NavigablePath.java +++ b/hibernate-core/src/main/java/org/hibernate/spi/NavigablePath.java @@ -8,10 +8,12 @@ import java.util.Objects; import org.hibernate.Incubating; -import org.hibernate.internal.util.StringHelper; import org.checkerframework.checker.nullness.qual.Nullable; +import static org.hibernate.internal.util.StringHelper.isEmpty; +import static org.hibernate.internal.util.StringHelper.nullIfEmpty; + /** * A compound name where the root path element is an entity name or a collection role * and each the path sub-path from the root references a domain or mapping model part @@ -35,10 +37,9 @@ public NavigablePath(String localName) { public NavigablePath(String rootName, @Nullable String alias) { this.parent = null; - this.alias = alias = StringHelper.nullIfEmpty( alias ); + this.alias = alias = nullIfEmpty( alias ); this.localName = rootName; this.identifierForTableGroup = rootName; - this.hashCode = localName.hashCode() + ( alias == null ? 0 : alias.hashCode() ); } @@ -48,14 +49,12 @@ public NavigablePath(NavigablePath parent, String navigableName) { public NavigablePath(NavigablePath parent, String localName, @Nullable String alias) { assert parent != null; - this.parent = parent; - this.alias = alias = StringHelper.nullIfEmpty( alias ); - - final String aliasedLocalName = alias == null - ? localName - : localName + '(' + alias + ')'; - + this.alias = alias = nullIfEmpty( alias ); + final String aliasedLocalName = + alias == null + ? localName + : localName + '(' + alias + ')'; this.hashCode = parent.hashCode() + aliasedLocalName.hashCode(); // the _identifierMapper is a "hidden property" on entities with composite keys. @@ -68,9 +67,10 @@ public NavigablePath(NavigablePath parent, String localName, @Nullable String al else { this.localName = localName; final String parentFullPath = parent.getFullPath(); - this.identifierForTableGroup = StringHelper.isEmpty( parentFullPath ) - ? aliasedLocalName - : parentFullPath + "." + localName; + this.identifierForTableGroup = + isEmpty( parentFullPath ) + ? aliasedLocalName + : parentFullPath + "." + localName; } } @@ -83,7 +83,7 @@ public NavigablePath( this.parent = parent; this.localName = localName; this.hashCode = hashCode; - this.alias = StringHelper.nullIfEmpty( alias ); + this.alias = nullIfEmpty( alias ); this.identifierForTableGroup = identifierForTableGroup; } @@ -119,32 +119,27 @@ public boolean equals(@Nullable Object other) { if ( this == other ) { return true; } - - if ( other == null ) { - return false; - } - - final DotIdentifierSequence otherPath = (DotIdentifierSequence) other; - if ( ! localNamesMatch( otherPath ) ) { + else if ( !(other instanceof DotIdentifierSequence otherPath) ) { return false; } - - if ( otherPath instanceof NavigablePath otherNavigablePath ) { - if ( ! Objects.equals( getAlias(), otherNavigablePath.getAlias() ) ) { + else { + if ( !localNamesMatch( otherPath ) ) { return false; } - return Objects.equals( getRealParent(), otherNavigablePath.getRealParent() ); + else if ( otherPath instanceof NavigablePath otherNavigablePath ) { + return Objects.equals( getAlias(), otherNavigablePath.getAlias() ) + && Objects.equals( getRealParent(), otherNavigablePath.getRealParent() ); + } + else { + return Objects.equals( getParent(), otherPath.getParent() ); + } } - - return Objects.equals( getParent(), otherPath.getParent() ); } protected boolean localNamesMatch(DotIdentifierSequence other) { - if ( other instanceof EntityIdentifierNavigablePath entityIdentifierNavigablePath ) { - return localNamesMatch( entityIdentifierNavigablePath ); - } - - return Objects.equals( getLocalName(), other.getLocalName() ); + return other instanceof EntityIdentifierNavigablePath entityIdentifierNavigablePath + ? localNamesMatch( entityIdentifierNavigablePath ) + : Objects.equals( getLocalName(), other.getLocalName() ); } protected boolean localNamesMatch(EntityIdentifierNavigablePath other) { @@ -192,11 +187,14 @@ public boolean isSuffix(@Nullable DotIdentifierSequence dotIdentifierSequence) { if ( dotIdentifierSequence == null ) { return true; } - if ( !localNamesMatch( dotIdentifierSequence ) ) { + else if ( !localNamesMatch( dotIdentifierSequence ) ) { return false; } - NavigablePath parent = getParent(); - return parent != null && parent.isSuffix( dotIdentifierSequence.getParent() ); + else { + final NavigablePath parent = getParent(); + return parent != null + && parent.isSuffix( dotIdentifierSequence.getParent() ); + } } /** @@ -214,14 +212,15 @@ public boolean isSuffix(@Nullable DotIdentifierSequence dotIdentifierSequence) { if ( suffix == null ) { return this; } - if ( !getLocalName().equals( suffix.getLocalName() ) ) { + else if ( !getLocalName().equals( suffix.getLocalName() ) ) { return null; } - NavigablePath parent = getParent(); - if ( parent != null ) { - return parent.trimSuffix( suffix.getParent() ); + else { + final NavigablePath parent = getParent(); + return parent != null + ? parent.trimSuffix( suffix.getParent() ) + : null; } - return null; } /** @@ -237,9 +236,13 @@ public boolean isParentOrEqual(@Nullable NavigablePath navigablePath) { return false; } - public boolean pathsMatch(@Nullable NavigablePath p) { - return this == p || p != null && localName.equals( p.localName ) - && ( parent == null ? p.parent == null && Objects.equals( alias, p.alias ) : parent.pathsMatch( p.parent ) ); + public boolean pathsMatch(@Nullable NavigablePath path) { + return this == path + || path != null && localName.equals( path.localName ) && ( + parent == null + ? path.parent == null && Objects.equals( alias, path.alias ) + : parent.pathsMatch( path.parent ) + ); } /** @@ -255,7 +258,7 @@ public boolean pathsMatch(@Nullable NavigablePath p) { // - this = Root.sub.leaf.terminal // - result = leaf.terminal - final RelativePathCollector pathCollector = new RelativePathCollector(); + final var pathCollector = new RelativePathCollector(); relativize( base, pathCollector ); return pathCollector.resolve(); } @@ -265,18 +268,16 @@ protected static class RelativePathCollector { private StringBuilder buffer; public void collectPath(String path) { - if ( !matchedBase ) { - return; + if ( matchedBase ) { + if ( buffer == null ) { + buffer = new StringBuilder(); + } + else { + buffer.append( '.' ); + } + + buffer.append( path ); } - - if ( buffer == null ) { - buffer = new StringBuilder(); - } - else { - buffer.append( '.' ); - } - - buffer.append( path ); } public @Nullable String resolve() { @@ -284,28 +285,31 @@ public void collectPath(String path) { // Return an empty string instead of null in case the two navigable paths are equal return matchedBase ? "" : null; } - return buffer.toString(); + else { + return buffer.toString(); + } } } protected void relativize(NavigablePath base, RelativePathCollector collector) { if ( this.equals( base ) ) { collector.matchedBase = true; - return; } - - if ( ! collector.matchedBase ) { - if ( parent != null ) { - parent.relativize( base, collector ); + else { + if ( !collector.matchedBase ) { + if ( parent != null ) { + parent.relativize( base, collector ); + } } + collector.collectPath( getLocalName() ); } - - collector.collectPath( getLocalName() ); } @Override public String getFullPath() { - return alias == null ? identifierForTableGroup : identifierForTableGroup + "(" + alias + ")"; + return alias == null + ? identifierForTableGroup + : identifierForTableGroup + "(" + alias + ")"; } @Override