diff --git a/hibernate-core/src/main/java/org/hibernate/boot/query/HbmResultSetMappingDescriptor.java b/hibernate-core/src/main/java/org/hibernate/boot/query/HbmResultSetMappingDescriptor.java index acc2188069..ea6ccf511d 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/query/HbmResultSetMappingDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/HbmResultSetMappingDescriptor.java @@ -11,6 +11,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; @@ -662,8 +663,11 @@ public class HbmResultSetMappingDescriptor implements NamedResultSetMappingDescr for ( int i = 1; i < propertyPathParts.length; i++ ) { if ( ! ( fetchable instanceof FetchableContainer ) ) { throw new MappingException( - "Non-terminal property path [" + navigablePath.getFullPath() - + " did not reference FetchableContainer" + String.format( + Locale.ROOT, + "Non-terminal property path did not reference FetchableContainer - %s ", + navigablePath + ) ); } fetchable = (Fetchable) ( (FetchableContainer) fetchable ).findSubPart( propertyPathParts[i], null ); @@ -869,7 +873,11 @@ public class HbmResultSetMappingDescriptor implements NamedResultSetMappingDescr this.tableAlias = hbmCollectionReturn.getAlias(); if ( tableAlias == null ) { throw new MappingException( - " did not specify alias [" + collectionPath.getFullPath() + "]" + String.format( + Locale.ROOT, + " did not specify alias - %s", + collectionPath + ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/query/SqlResultSetMappingDescriptor.java b/hibernate-core/src/main/java/org/hibernate/boot/query/SqlResultSetMappingDescriptor.java index 56b6a1b493..09a3318248 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/query/SqlResultSetMappingDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/query/SqlResultSetMappingDescriptor.java @@ -407,8 +407,11 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr for ( int i = 1; i < propertyPathParts.length; i++ ) { if ( ! ( subPart instanceof ModelPartContainer ) ) { throw new MappingException( - "Non-terminal property path [" + navigablePath.getFullPath() - + " did not reference FetchableContainer" + String.format( + Locale.ROOT, + "Non-terminal property path did not reference FetchableContainer - %s ", + navigablePath + ) ); } navigablePath = navigablePath.append( propertyPathParts[ i ] ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java index 9b00440460..5dd58d098c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/ToOneAttributeMapping.java @@ -899,8 +899,8 @@ public class ToOneAttributeMapping final NavigablePath parentPath = grandparentNavigablePath.getParent(); // This can be null for a collection loader if ( parentPath == null ) { - return grandparentNavigablePath.getFullPath().equals( - entityMappingType.findSubPart( bidirectionalAttributeName ).getNavigableRole().getFullPath() + return grandparentNavigablePath.equals( + entityMappingType.findSubPart( bidirectionalAttributeName ).getNavigableRole() ); } else { diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/QualifiedJoinPredicatePathConsumer.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/QualifiedJoinPredicatePathConsumer.java index 8463ae1c54..135d5d2114 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/QualifiedJoinPredicatePathConsumer.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/QualifiedJoinPredicatePathConsumer.java @@ -78,8 +78,8 @@ public class QualifiedJoinPredicatePathConsumer extends BasicDotIdentifierConsum String.format( Locale.ROOT, "SqmQualifiedJoin predicate referred to SqmRoot [`%s`] other than the join's root [`%s`]", - pathRoot.getNavigablePath().getFullPath(), - sqmJoin.getNavigablePath().getFullPath() + pathRoot.getNavigablePath(), + sqmJoin.getNavigablePath() ) ); } @@ -110,8 +110,8 @@ public class QualifiedJoinPredicatePathConsumer extends BasicDotIdentifierConsum String.format( Locale.ROOT, "SqmQualifiedJoin predicate referred to SqmRoot [`%s`] other than the join's root [`%s`]", - pathRoot.getNavigablePath().getFullPath(), - sqmJoin.getNavigablePath().getFullPath() + pathRoot.getNavigablePath(), + sqmJoin.getNavigablePath() ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java index 1d5e70e769..b2c2fdf368 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java @@ -2291,7 +2291,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem throw new NotYetImplementedFor6Exception( "Path continuation from `id()` reference not yet implemented" ); } - throw new SemanticException( "Path does not resolve to an entity type '" + sqmPath.getNavigablePath().getFullPath() + "'" ); + throw new SemanticException( "Path does not resolve to an entity type '" + sqmPath.getNavigablePath() + "'" ); } @Override @@ -2312,7 +2312,8 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem throw new SemanticException( String.format( "Path '%s' resolved to entity type '%s' which does not define a version", - sqmPath.getNavigablePath().getFullPath(), identifiableType.getTypeName() + sqmPath.getNavigablePath(), + identifiableType.getTypeName() ) ); } @@ -2320,7 +2321,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem return sqmPath.get( versionAttribute ); } - throw new SemanticException( "Path does not resolve to an entity type '" + sqmPath.getNavigablePath().getFullPath() + "'" ); + throw new SemanticException( "Path does not resolve to an entity type '" + sqmPath.getNavigablePath() + "'" ); } @Override @@ -2341,7 +2342,8 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem throw new SemanticException( String.format( "Path '%s' resolved to entity type '%s' which does not define a natural id", - sqmPath.getNavigablePath().getFullPath(), identifiableType.getTypeName() + sqmPath.getNavigablePath(), + identifiableType.getTypeName() ) ); } @@ -2349,7 +2351,8 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem throw new SemanticException( String.format( "Path '%s' resolved to entity type '%s' which defines multiple natural ids", - sqmPath.getNavigablePath().getFullPath(), identifiableType.getTypeName() + sqmPath.getNavigablePath(), + identifiableType.getTypeName() ) ); } @@ -2360,7 +2363,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem return sqmPath.get( naturalIdAttribute ); } - throw new SemanticException( "Path does not resolve to an entity type '" + sqmPath.getNavigablePath().getFullPath() + "'" ); + throw new SemanticException( "Path does not resolve to an entity type '" + sqmPath.getNavigablePath() + "'" ); } @Override @@ -2381,7 +2384,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implem String.format( Locale.ROOT, "`%s` used in `fk()` only supported for to-one mappings, but found `%s`", - sqmPath.getNavigablePath().getFullPath(), + sqmPath.getNavigablePath(), toOneReference ) ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SqmPathRegistryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SqmPathRegistryImpl.java index de48246dee..2457e9ea3c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SqmPathRegistryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SqmPathRegistryImpl.java @@ -55,7 +55,7 @@ public class SqmPathRegistryImpl implements SqmPathRegistry { @Override public void register(SqmPath sqmPath) { - SqmTreeCreationLogger.LOGGER.tracef( "SqmProcessingIndex#register(SqmPath) : %s", sqmPath.getNavigablePath().getFullPath() ); + SqmTreeCreationLogger.LOGGER.tracef( "SqmProcessingIndex#register(SqmPath) : %s", sqmPath.getNavigablePath() ); // Generally we: // 1) add the path to the path-by-path map diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownPathException.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownPathException.java index 88febbdab1..d925631f9e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownPathException.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/UnknownPathException.java @@ -26,7 +26,7 @@ public class UnknownPathException extends SemanticException { "Could not resolve path `%s` relative to %s (%s)", name, base.getReferencedPathSource().getSqmPathType().getTypeName(), - base.getNavigablePath().getFullPath() + base.getNavigablePath() ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmTreePrinter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmTreePrinter.java index 3ad794fb37..7d0ad512c0 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmTreePrinter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmTreePrinter.java @@ -283,7 +283,7 @@ public class SqmTreePrinter implements SemanticQueryWalker { processStanza( "delete", () -> { - logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath().getFullPath() ); + logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath() ); visitWhereClause( statement.getWhereClause() ); } ); @@ -298,7 +298,7 @@ public class SqmTreePrinter implements SemanticQueryWalker { processStanza( "insert", () -> { - logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath().getFullPath() ); + logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath() ); processStanza( "into", () -> statement.getInsertionTargetPaths().forEach( sqmPath -> sqmPath.accept( this ) ) @@ -317,7 +317,7 @@ public class SqmTreePrinter implements SemanticQueryWalker { processStanza( "insert", () -> { - logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath().getFullPath() ); + logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath() ); processStanza( "into", () -> statement.getInsertionTargetPaths().forEach( sqmPath -> sqmPath.accept( this ) ) @@ -361,7 +361,7 @@ public class SqmTreePrinter implements SemanticQueryWalker { processStanza( statement.isVersioned() ? "update versioned" : "update", () -> { - logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath().getFullPath() ); + logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath() ); visitSetClause( statement.getSetClause() ); @@ -495,7 +495,7 @@ public class SqmTreePrinter implements SemanticQueryWalker { public Object visitRootPath(SqmRoot sqmRoot) { processStanza( "root", - '`' + sqmRoot.getNavigablePath().getFullPath() + '`', + "`" + sqmRoot.getNavigablePath() + "`", () -> processJoins( sqmRoot ) ); @@ -517,7 +517,7 @@ public class SqmTreePrinter implements SemanticQueryWalker { public Object visitCrossJoin(SqmCrossJoin joinedFromElement) { processStanza( "cross", - '`' + joinedFromElement.getNavigablePath().getFullPath() + '`', + "`" + joinedFromElement.getNavigablePath() + "`", () -> processJoins( joinedFromElement ) ); @@ -528,7 +528,7 @@ public class SqmTreePrinter implements SemanticQueryWalker { public Object visitPluralPartJoin(SqmPluralPartJoin joinedFromElement) { processStanza( "plural-part", - '`' + joinedFromElement.getNavigablePath().getFullPath() + '`', + "`" + joinedFromElement.getNavigablePath() + "`", () -> processJoins( joinedFromElement ) ); @@ -552,12 +552,12 @@ public class SqmTreePrinter implements SemanticQueryWalker { @Override public Object visitQualifiedEntityJoin(SqmEntityJoin joinedFromElement) { if ( inJoinPredicate ) { - logWithIndentation( "-> [joined-path] - `%s`", joinedFromElement.getNavigablePath().getFullPath() ); + logWithIndentation( "-> [joined-path] - `%s`", joinedFromElement.getNavigablePath() ); } else { processStanza( "entity", - '`' + joinedFromElement.getNavigablePath().getFullPath() + '`', + "`" + joinedFromElement.getNavigablePath() + "`", () -> { processJoinPredicate( joinedFromElement ); processJoins( joinedFromElement ); @@ -570,12 +570,12 @@ public class SqmTreePrinter implements SemanticQueryWalker { @Override public Object visitQualifiedAttributeJoin(SqmAttributeJoin joinedFromElement) { if ( inJoinPredicate ) { - logWithIndentation( "-> [joined-path] - `%s`", joinedFromElement.getNavigablePath().getFullPath() ); + logWithIndentation( "-> [joined-path] - `%s`", joinedFromElement.getNavigablePath() ); } else { processStanza( "attribute", - '`' + joinedFromElement.getNavigablePath().getFullPath() + '`', + "`" + joinedFromElement.getNavigablePath() + "`", () -> { logIndented( "[fetched = " + joinedFromElement.isFetched() + ']' ); @@ -589,56 +589,56 @@ public class SqmTreePrinter implements SemanticQueryWalker { @Override public Object visitBasicValuedPath(SqmBasicValuedSimplePath path) { - logWithIndentation( "-> [basic-path] - `%s`", path.getNavigablePath().getFullPath() ); + logWithIndentation( "-> [basic-path] - `%s`", path.getNavigablePath() ); return null; } @Override public Object visitEmbeddableValuedPath(SqmEmbeddedValuedSimplePath path) { - logWithIndentation( "-> [embedded-path] - `%s`", path.getNavigablePath().getFullPath() ); + logWithIndentation( "-> [embedded-path] - `%s`", path.getNavigablePath() ); return null; } @Override public Object visitAnyValuedValuedPath(SqmAnyValuedSimplePath path) { - logWithIndentation( "-> [any-path] - `%s`", path.getNavigablePath().getFullPath() ); + logWithIndentation( "-> [any-path] - `%s`", path.getNavigablePath() ); return null; } @Override public Object visitNonAggregatedCompositeValuedPath(NonAggregatedCompositeSimplePath path) { - logWithIndentation( "-> [non-aggregated-composite-path] - `%s`", path.getNavigablePath().getFullPath() ); + logWithIndentation( "-> [non-aggregated-composite-path] - `%s`", path.getNavigablePath() ); return null; } @Override public Object visitFkExpression(SqmFkExpression fkExpression) { - logWithIndentation( "-> [fk-ref] - `%s`", fkExpression.getToOnePath().getNavigablePath().getFullPath() ); + logWithIndentation( "-> [fk-ref] - `%s`", fkExpression.getToOnePath().getNavigablePath() ); return null; } @Override public Object visitSelfInterpretingSqmPath(SelfInterpretingSqmPath sqmPath) { - logWithIndentation( "-> [self-interpreting-path] - `%s`", sqmPath.getNavigablePath().getFullPath() ); + logWithIndentation( "-> [self-interpreting-path] - `%s`", sqmPath.getNavigablePath() ); return null; } @Override public Object visitEntityValuedPath(SqmEntityValuedSimplePath path) { - logWithIndentation( "-> [entity-path] - `%s`", path.getNavigablePath().getFullPath() ); + logWithIndentation( "-> [entity-path] - `%s`", path.getNavigablePath() ); return null; } @Override public Object visitPluralValuedPath(SqmPluralValuedSimplePath path) { - logWithIndentation( "-> [plural-path] - `%s`", path.getNavigablePath().getFullPath() ); + logWithIndentation( "-> [plural-path] - `%s`", path.getNavigablePath() ); return null; } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java index 7922bf89a6..1fadf68a00 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/BasicValuedPathInterpretation.java @@ -85,7 +85,7 @@ public class BasicValuedPathInterpretation extends AbstractSqmPathInterpretat } } - throw new SemanticException( "`" + sqmPath.getNavigablePath().getFullPath() + "` did not reference a known model part" ); + throw new SemanticException( "`" + sqmPath.getNavigablePath() + "` did not reference a known model part" ); } final TableReference tableReference = tableGroup.resolveTableReference( @@ -148,7 +148,7 @@ public class BasicValuedPathInterpretation extends AbstractSqmPathInterpretat @Override public String toString() { - return "BasicValuedPathInterpretation(" + getNavigablePath().getFullPath() + ')'; + return "BasicValuedPathInterpretation(" + getNavigablePath() + ")"; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/EmbeddableValuedPathInterpretation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/EmbeddableValuedPathInterpretation.java index cc21f17e5e..cce2af3bf6 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/EmbeddableValuedPathInterpretation.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/EmbeddableValuedPathInterpretation.java @@ -102,7 +102,7 @@ public class EmbeddableValuedPathInterpretation extends AbstractSqmPathInterp @Override public String toString() { - return "EmbeddableValuedPathInterpretation(" + getNavigablePath().getFullPath() + ')'; + return "EmbeddableValuedPathInterpretation(" + getNavigablePath() + ")"; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmFrom.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmFrom.java index 92dbce327e..0b3ef74c9c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmFrom.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmFrom.java @@ -434,7 +434,7 @@ public abstract class AbstractSqmFrom extends AbstractSqmPath implements "Passed attribute name [%s] did not correspond to a collection (bag) reference [%s] relative to %s", attributeName, joinedPathSource, - getNavigablePath().getFullPath() + getNavigablePath() ) ); } @@ -465,7 +465,7 @@ public abstract class AbstractSqmFrom extends AbstractSqmPath implements "Passed attribute name [%s] did not correspond to a collection (set) reference [%s] relative to %s", attributeName, joinedPathSource, - getNavigablePath().getFullPath() + getNavigablePath() ) ); } @@ -496,7 +496,7 @@ public abstract class AbstractSqmFrom extends AbstractSqmPath implements "Passed attribute name [%s] did not correspond to a collection (list) reference [%s] relative to %s", attributeName, joinedPathSource, - getNavigablePath().getFullPath() + getNavigablePath() ) ); } @@ -527,7 +527,7 @@ public abstract class AbstractSqmFrom extends AbstractSqmPath implements "Passed attribute name [%s] did not correspond to a collection (map) reference [%s] relative to %s", attributeName, joinedPathSource, - getNavigablePath().getFullPath() + getNavigablePath() ) ); } @@ -659,7 +659,7 @@ public abstract class AbstractSqmFrom extends AbstractSqmPath implements "Passed attribute [%s] did not correspond to a joinable reference [%s] relative to %s", joinedPathSource.getPathName(), joinedPathSource, - getNavigablePath().getFullPath() + getNavigablePath() ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java index c7117e8564..a90a2bf2cf 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java @@ -195,6 +195,6 @@ public abstract class AbstractSqmPath extends AbstractSqmExpression implem @Override public String toString() { - return getClass().getSimpleName() + "(" + navigablePath.getFullPath() + ")"; + return getClass().getSimpleName() + "(" + navigablePath + ")"; } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPluralPartJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPluralPartJoin.java index d002502b4b..aa80853556 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPluralPartJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPluralPartJoin.java @@ -128,7 +128,7 @@ public class SqmPluralPartJoin extends AbstractSqmJoin implements SqmQ return String.format( Locale.ROOT, "SqmPluralPartJoin(%s : %s)", - getNavigablePath().getFullPath(), + getNavigablePath(), getReferencedPathSource().getPathName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmSingularJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmSingularJoin.java index bc7c327fab..5c27e55128 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmSingularJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmSingularJoin.java @@ -126,7 +126,7 @@ public class SqmSingularJoin extends AbstractSqmAttributeJoin { return String.format( Locale.ROOT, "SqmSingularJoin(%s : %s)", - getNavigablePath().getFullPath(), + getNavigablePath(), getReferencedPathSource().getPathName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/spi/DotIdentifierSequence.java b/hibernate-core/src/main/java/org/hibernate/spi/DotIdentifierSequence.java index f2805d798f..2b8c670145 100644 --- a/hibernate-core/src/main/java/org/hibernate/spi/DotIdentifierSequence.java +++ b/hibernate-core/src/main/java/org/hibernate/spi/DotIdentifierSequence.java @@ -30,6 +30,9 @@ public interface DotIdentifierSequence { /** * The full sequence text. E.g., given the sequence `a.b.c`, * this returns `a.b.c` + * + * @implNote This method may dynamically build the returned + * String and should be avoided for critical paths (comparisons, e.g.). */ String getFullPath(); diff --git a/hibernate-core/src/main/java/org/hibernate/spi/EntityIdentifierNavigablePath.java b/hibernate-core/src/main/java/org/hibernate/spi/EntityIdentifierNavigablePath.java index e2b222cf1f..ee23398c3f 100644 --- a/hibernate-core/src/main/java/org/hibernate/spi/EntityIdentifierNavigablePath.java +++ b/hibernate-core/src/main/java/org/hibernate/spi/EntityIdentifierNavigablePath.java @@ -24,62 +24,79 @@ public class EntityIdentifierNavigablePath extends NavigablePath { this.identifierAttributeName = identifierAttributeName; } + public String getIdentifierAttributeName() { + return identifierAttributeName; + } + @Override public String getLocalName() { return EntityIdentifierMapping.ROLE_LOCAL_NAME; } @Override - public int hashCode() { - return getParent().getFullPath().hashCode(); - } - - @Override - public boolean equals(Object other) { - if ( other == null ) { - return false; - } - - if ( other == this ) { - return true; - } - - if ( ! ( other instanceof NavigablePath ) ) { - return false; - } - - final NavigablePath otherPath = (NavigablePath) other; - - if ( getFullPath().equals( ( (NavigablePath) other ).getFullPath() ) ) { - return true; - } - - if ( getParent() == null ) { - if ( otherPath.getParent() != null ) { - return false; - } - - //noinspection RedundantIfStatement - if ( localNamesMatch( otherPath) ) { - return true; - - } - - return false; - } - - if ( otherPath.getParent() == null ) { - return false; - } - - return getParent().equals( otherPath.getParent() ) - && localNamesMatch( otherPath ); - } - - private boolean localNamesMatch(NavigablePath otherPath) { + protected boolean localNamesMatch(DotIdentifierSequence otherPath) { final String otherLocalName = otherPath.getLocalName(); return otherLocalName.equals( getLocalName() ) || otherLocalName.equals( identifierAttributeName ); } + + @Override + protected boolean localNamesMatch(EntityIdentifierNavigablePath otherPath) { + return super.localNamesMatch( otherPath ); + } + +// @Override +// public int hashCode() { +// return getParent().getFullPath().hashCode(); +// } +// +// @Override +// public boolean equals(Object other) { +// if ( other == null ) { +// return false; +// } +// +// if ( other == this ) { +// return true; +// } +// +// if ( ! ( other instanceof NavigablePath ) ) { +// return false; +// } +// +// final NavigablePath otherPath = (NavigablePath) other; +// +// if ( getFullPath().equals( ( (NavigablePath) other ).getFullPath() ) ) { +// return true; +// } +// +// if ( getParent() == null ) { +// if ( otherPath.getParent() != null ) { +// return false; +// } +// +// //noinspection RedundantIfStatement +// if ( localNamesMatch( otherPath) ) { +// return true; +// +// } +// +// return false; +// } +// +// if ( otherPath.getParent() == null ) { +// return false; +// } +// +// return getParent().equals( otherPath.getParent() ) +// && localNamesMatch( otherPath ); +// } +// +// private boolean localNamesMatch(NavigablePath otherPath) { +// final String otherLocalName = otherPath.getLocalName(); +// +// return otherLocalName.equals( getLocalName() ) +// || otherLocalName.equals( identifierAttributeName ); +// } } 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 9a5d102483..44d33a3088 100644 --- a/hibernate-core/src/main/java/org/hibernate/spi/NavigablePath.java +++ b/hibernate-core/src/main/java/org/hibernate/spi/NavigablePath.java @@ -7,6 +7,7 @@ package org.hibernate.spi; import java.io.Serializable; +import java.util.Objects; import org.hibernate.Incubating; import org.hibernate.internal.util.StringHelper; @@ -25,41 +26,9 @@ public class NavigablePath implements DotIdentifierSequence, Serializable { private final NavigablePath parent; private final String localName; private final String alias; - private final String identifierForTableGroup; - - private final String fullPath; - - public NavigablePath(NavigablePath parent, String navigableName) { - this.parent = parent; - this.alias = null; - - // 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( navigableName ) ) { - this.localName = ""; - this.identifierForTableGroup = parent != null ? parent.getIdentifierForTableGroup() : ""; - - this.fullPath = parent != null ? parent.getFullPath() : ""; - } - else { - this.localName = navigableName; - if ( parent != null ) { - final String parentFullPath = parent.getFullPath(); - this.fullPath = StringHelper.isEmpty( parentFullPath ) - ? navigableName - : parentFullPath + "." + navigableName; - this.identifierForTableGroup = StringHelper.isEmpty( parent.getIdentifierForTableGroup() ) - ? navigableName - : parent.getIdentifierForTableGroup() + "." + navigableName; - } - else { - this.fullPath = navigableName; - this.identifierForTableGroup = navigableName; - } - } - } + private final FullPathCalculator fullPathCalculator; + private final int hashCode; public NavigablePath(String localName) { this( localName, null ); @@ -67,88 +36,69 @@ public class NavigablePath implements DotIdentifierSequence, Serializable { public NavigablePath(String rootName, String alias) { this.parent = null; - this.alias = StringHelper.nullIfEmpty( alias ); + this.alias = alias = StringHelper.nullIfEmpty( alias ); this.localName = rootName; this.identifierForTableGroup = rootName; - this.fullPath = alias == null ? rootName : rootName + "(" + alias + ")"; + this.fullPathCalculator = NavigablePath::calculateRootFullPath; + + this.hashCode = localName.hashCode() + ( alias == null ? 0 : alias.hashCode() ); } - public NavigablePath(NavigablePath parent, String property, String alias) { - alias = StringHelper.nullIfEmpty( alias ); - final String navigableName = alias == null - ? property - : property + '(' + alias + ')'; + public NavigablePath(NavigablePath parent, String navigableName) { + this( parent, navigableName, null ); + } + + public NavigablePath(NavigablePath parent, String localName, String alias) { + assert parent != null; this.parent = parent; - this.alias = alias; + this.alias = alias = StringHelper.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. // 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( navigableName ) ) { - this.fullPath = parent != null ? parent.getFullPath() : ""; + if ( IDENTIFIER_MAPPER_PROPERTY.equals( localName ) ) { this.localName = ""; - identifierForTableGroup = parent != null ? parent.getFullPath() : ""; + this.identifierForTableGroup = parent.getFullPath(); + this.fullPathCalculator = NavigablePath::calculateIdMapperFullPath; } else { - this.localName = property; - if ( parent != null ) { - final String parentFullPath = parent.getFullPath(); - this.fullPath = StringHelper.isEmpty( parentFullPath ) - ? navigableName - : parentFullPath + "." + navigableName; - this.identifierForTableGroup = StringHelper.isEmpty( parent.getIdentifierForTableGroup() ) - ? navigableName - : parent.getIdentifierForTableGroup() + "." + property; - } - else { - this.fullPath = navigableName; - this.identifierForTableGroup = property; - } + this.localName = localName; + this.identifierForTableGroup = StringHelper.isEmpty( parent.getIdentifierForTableGroup() ) + ? aliasedLocalName + : parent.getIdentifierForTableGroup() + "." + localName; + this.fullPathCalculator = NavigablePath::calculateNormalFullPath; } } - public NavigablePath() { - this( "" ); - } - public NavigablePath( NavigablePath parent, - String fullPath, String localName, - String identifierForTableGroup) { + String alias, + String identifierForTableGroup, + FullPathCalculator fullPathCalculator, + int hashCode) { this.parent = parent; - this.alias = null; - this.fullPath = fullPath; this.localName = localName; + this.hashCode = hashCode; + this.alias = StringHelper.nullIfEmpty( alias ); this.identifierForTableGroup = identifierForTableGroup; + this.fullPathCalculator = fullPathCalculator; } - public NavigablePath treatAs(String entityName) { - return new TreatedNavigablePath( this, entityName ); - } - - public NavigablePath treatAs(String entityName, String alias) { - return new TreatedNavigablePath( this, entityName, alias ); - } - - public NavigablePath append(String property) { - return new NavigablePath( this, property ); - } - - public NavigablePath append(String property, String alias) { - return new NavigablePath( this, property, alias ); - } - + @Override public NavigablePath getParent() { return parent instanceof TreatedNavigablePath ? parent.getParent() : parent; } - public NavigablePath getRealParent() { - return parent; - } - + @Override public String getLocalName() { return localName; } @@ -162,17 +112,75 @@ public class NavigablePath implements DotIdentifierSequence, Serializable { } public String getIdentifierForTableGroup() { - // todo (6.0) : is this `if` really needed? seems this is already handled in constructors - if ( parent == null ) { - return fullPath; - } return identifierForTableGroup; } - public String getFullPath() { - return fullPath; + @Override + public int hashCode() { + return hashCode; } + @Override + public boolean equals(Object other) { + if ( this == other ) { + return true; + } + + if ( other == null ) { + return false; + } + + final DotIdentifierSequence otherPath = (DotIdentifierSequence) other; + if ( ! localNamesMatch( otherPath ) ) { + return false; + } + + if ( otherPath instanceof NavigablePath ) { + final NavigablePath otherNavigablePath = (NavigablePath) otherPath; + if ( ! Objects.equals( getAlias(), otherNavigablePath.getAlias() ) ) { + return false; + } + } + + return Objects.equals( getParent(), otherPath.getParent() ); + } + + protected boolean localNamesMatch(DotIdentifierSequence other) { + if ( other instanceof EntityIdentifierNavigablePath ) { + return localNamesMatch( (EntityIdentifierNavigablePath) other ); + } + + return Objects.equals( getLocalName(), other.getLocalName() ); + } + + protected boolean localNamesMatch(EntityIdentifierNavigablePath other) { + return Objects.equals( getLocalName(), other.getLocalName() ) + || Objects.equals( getLocalName(), other.getIdentifierAttributeName() ); + } + + public NavigablePath append(String property) { + return new NavigablePath( this, property ); + } + + public NavigablePath append(String property, String alias) { + return new NavigablePath( this, property, alias ); + } + + public NavigablePath treatAs(String entityName) { + return new TreatedNavigablePath( this, entityName ); + } + + public NavigablePath treatAs(String entityName, String alias) { + return new TreatedNavigablePath( this, entityName, alias ); + } + + public NavigablePath getRealParent() { + return parent; + } + + /** + * Determine whether this path is part of the given path's parent + */ public boolean isParent(NavigablePath navigablePath) { while ( navigablePath != null ) { if ( this.equals( navigablePath.getParent() ) ) { @@ -183,45 +191,49 @@ public class NavigablePath implements DotIdentifierSequence, Serializable { return false; } + @Override + public String getFullPath() { + return fullPathCalculator.calculateFullPath( parent, localName, alias ); + } + @Override public String toString() { - return fullPath; + return getFullPath(); } - @Override - public int hashCode() { - return fullPath.hashCode(); + /** + * Effectively a tri-function + */ + @FunctionalInterface + protected interface FullPathCalculator extends Serializable { + String calculateFullPath(NavigablePath parent, String localName, String alias); } - @Override - public boolean equals(Object other) { - if ( this == other ) { - return true; - } + /** + * The pattern used for root NavigablePaths + */ + protected static String calculateRootFullPath(NavigablePath parent, String rootName, String alias) { + assert parent == null; + return alias == null ? rootName : rootName + "(" + alias + ")"; + } - if ( other instanceof EntityIdentifierNavigablePath ) { - final EntityIdentifierNavigablePath otherPath = (EntityIdentifierNavigablePath) other; - return otherPath.equals( this ); - } + /** + * The normal pattern used for the "full path" + */ + private static String calculateNormalFullPath(NavigablePath parent, String localName, String alias) { + assert parent != null; - if ( ! ( other instanceof NavigablePath ) ) { - return false; - } + final String parentFullPath = parent.getFullPath(); + final String baseFullPath = StringHelper.isEmpty( parentFullPath ) + ? localName + : parentFullPath + "." + localName; + return alias == null ? baseFullPath : baseFullPath + "(" + alias + ")"; + } - final NavigablePath otherPath = (NavigablePath) other; - - // todo (6.0) : checking the full paths is definitely better performance - // But I'm not sure it is correct in all cases. Take cases referencing - // an identifier at some level - the actual EntityIdentifierNavigablePath - // subclass has special handling for one path using the "role name" (`"{id}"`) - // while the other might instead use the attribute name -// return Objects.equals( getFullPath(), otherPath.getFullPath() ); - - if ( getParent() == null ) { - return otherPath.getParent() == null; - } - - return getParent().equals( otherPath.getParent() ) - && getLocalName().equals( otherPath.getLocalName() ); + /** + * Pattern used for `_identifierMapper` + */ + protected static String calculateIdMapperFullPath(NavigablePath parent, String localName, String alias) { + return parent != null ? parent.getFullPath() : ""; } } diff --git a/hibernate-core/src/main/java/org/hibernate/spi/TreatedNavigablePath.java b/hibernate-core/src/main/java/org/hibernate/spi/TreatedNavigablePath.java index 09c575b006..d413866065 100644 --- a/hibernate-core/src/main/java/org/hibernate/spi/TreatedNavigablePath.java +++ b/hibernate-core/src/main/java/org/hibernate/spi/TreatedNavigablePath.java @@ -23,14 +23,21 @@ public class TreatedNavigablePath extends NavigablePath { public TreatedNavigablePath(NavigablePath parent, String entityTypeName, String alias) { super( parent, - alias == null ? "treat(" + parent.getFullPath() + " as " + entityTypeName + ")" - : "treat(" + parent.getFullPath() + " as " + entityTypeName + ")(" + alias + ")", entityTypeName, - "treat(" + parent.getFullPath() + " as " + entityTypeName + ")" + alias, + "treat(" + parent + " as " + entityTypeName + ")", + TreatedNavigablePath::calculateTreatedFullPath, + 1 ); assert !( parent instanceof TreatedNavigablePath ); } + protected static String calculateTreatedFullPath(NavigablePath parent, String localName, String alias) { + return alias == null + ? "treat(" + parent + " as " + localName + ")" + : "treat(" + parent + " as " + localName + ")(" + alias + ")"; + } + @Override public NavigablePath treatAs(String entityName) { return new TreatedNavigablePath( getRealParent(), entityName ); @@ -41,25 +48,25 @@ public class TreatedNavigablePath extends NavigablePath { return new TreatedNavigablePath( getRealParent(), entityName, alias ); } - @Override - public int hashCode() { - return getFullPath().hashCode(); - } - - @Override - public boolean equals(Object other) { - if ( other == null ) { - return false; - } - - if ( other == this ) { - return true; - } - - if ( ! ( other instanceof NavigablePath ) ) { - return false; - } - - return getFullPath().equals( ( (NavigablePath) other ).getFullPath() ); - } +// @Override +// public int hashCode() { +// return getFullPath().hashCode(); +// } +// +// @Override +// public boolean equals(Object other) { +// if ( other == null ) { +// return false; +// } +// +// if ( other == this ) { +// return true; +// } +// +// if ( ! ( other instanceof NavigablePath ) ) { +// return false; +// } +// +// return getFullPath().equals( ( (NavigablePath) other ).getFullPath() ); +// } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/AbstractColumnReferenceQualifier.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/AbstractColumnReferenceQualifier.java index 66b1c99790..6de34d4465 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/AbstractColumnReferenceQualifier.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/AbstractColumnReferenceQualifier.java @@ -46,7 +46,7 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc Locale.ROOT, "Unable to determine TableReference (`%s`) for `%s`", tableExpression, - navigablePath.getFullPath() + navigablePath ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/DerivedTableReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/DerivedTableReference.java index 61c2926e41..3cd23f1c2c 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/DerivedTableReference.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/DerivedTableReference.java @@ -49,7 +49,7 @@ public abstract class DerivedTableReference extends AbstractTableReference { boolean allowFkOptimization) { throw new UnknownTableReferenceException( tableExpression, - "TableReferences cannot be resolved relative to DerivedTableReferences - `" + tableExpression + "` : " + navigablePath.getFullPath() + "TableReferences cannot be resolved relative to DerivedTableReferences - `" + tableExpression + "` : " + navigablePath ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/LazyTableGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/LazyTableGroup.java index bf6516abd1..68518540c8 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/LazyTableGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/LazyTableGroup.java @@ -252,7 +252,7 @@ public class LazyTableGroup extends DelegatingTableGroup { Locale.ROOT, "Unable to determine TableReference (`%s`) for `%s`", tableExpression, - navigablePath.getFullPath() + navigablePath ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/MappedByTableGroup.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/MappedByTableGroup.java index d69c9d9714..de76d468c0 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/MappedByTableGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/MappedByTableGroup.java @@ -130,7 +130,7 @@ public class MappedByTableGroup extends DelegatingTableGroup implements VirtualT Locale.ROOT, "Unable to determine TableReference (`%s`) for `%s`", tableExpression, - navigablePath.getFullPath() + navigablePath ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/NamedTableReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/NamedTableReference.java index c4f784b2d8..8d0ff6526e 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/NamedTableReference.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/NamedTableReference.java @@ -89,7 +89,7 @@ public class NamedTableReference extends AbstractTableReference { Locale.ROOT, "Unable to determine TableReference (`%s`) for `%s`", tableExpression, - navigablePath.getFullPath() + navigablePath ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/UnionTableReference.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/UnionTableReference.java index d84846714c..8efdc2ef68 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/UnionTableReference.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/from/UnionTableReference.java @@ -43,7 +43,7 @@ public class UnionTableReference extends NamedTableReference { Locale.ROOT, "Unable to determine TableReference (`%s`) for `%s`", tableExpression, - navigablePath.getFullPath() + navigablePath ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java index f1a07a7d3f..6df39bdbd8 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/AbstractEntityInitializer.java @@ -290,7 +290,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces EntityLoadingLogging.ENTITY_LOADING_LOGGER.tracef( "(%s) Beginning Initializer#resolveKey process for entity : %s", StringHelper.collapse( this.getClass().getName() ), - getNavigablePath().getFullPath() + getNavigablePath() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultInitializer.java index 5d33146b43..06ff5c46f2 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityResultInitializer.java @@ -54,6 +54,6 @@ public class EntityResultInitializer extends AbstractEntityInitializer { @Override public String toString() { - return CONCRETE_NAME + "(" + getNavigablePath().getFullPath() + ")"; + return CONCRETE_NAME + "(" + getNavigablePath() + ")"; } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java index f9cc051e30..d50d793ee3 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/ResultsHelper.java @@ -119,7 +119,7 @@ public class ResultsHelper { initializerMap.forEach( (navigablePath, initializer) -> { ResultsLogger.RESULTS_MESSAGE_LOGGER.debugf( " %s -> %s@%s (%s)", - navigablePath.getFullPath(), + navigablePath, initializer, initializer.hashCode(), initializer.getInitializedPart()