HHH-15132 - Improvements for NavigablePath
- dropped `NavigablePath#fullPath` field - `#getFullPath` is now "(re)built" on demand - adjust uses of `NavigablePath#getFullPath` - refactor `NavigablePath` constructors
This commit is contained in:
parent
f474449e7d
commit
e496ec45ea
|
@ -11,6 +11,7 @@ import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
@ -662,8 +663,11 @@ public class HbmResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
||||||
for ( int i = 1; i < propertyPathParts.length; i++ ) {
|
for ( int i = 1; i < propertyPathParts.length; i++ ) {
|
||||||
if ( ! ( fetchable instanceof FetchableContainer ) ) {
|
if ( ! ( fetchable instanceof FetchableContainer ) ) {
|
||||||
throw new MappingException(
|
throw new MappingException(
|
||||||
"Non-terminal property path [" + navigablePath.getFullPath()
|
String.format(
|
||||||
+ " did not reference FetchableContainer"
|
Locale.ROOT,
|
||||||
|
"Non-terminal property path did not reference FetchableContainer - %s ",
|
||||||
|
navigablePath
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
fetchable = (Fetchable) ( (FetchableContainer) fetchable ).findSubPart( propertyPathParts[i], null );
|
fetchable = (Fetchable) ( (FetchableContainer) fetchable ).findSubPart( propertyPathParts[i], null );
|
||||||
|
@ -869,7 +873,11 @@ public class HbmResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
||||||
this.tableAlias = hbmCollectionReturn.getAlias();
|
this.tableAlias = hbmCollectionReturn.getAlias();
|
||||||
if ( tableAlias == null ) {
|
if ( tableAlias == null ) {
|
||||||
throw new MappingException(
|
throw new MappingException(
|
||||||
"<return-collection/> did not specify alias [" + collectionPath.getFullPath() + "]"
|
String.format(
|
||||||
|
Locale.ROOT,
|
||||||
|
"<return-collection/> did not specify alias - %s",
|
||||||
|
collectionPath
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -407,8 +407,11 @@ public class SqlResultSetMappingDescriptor implements NamedResultSetMappingDescr
|
||||||
for ( int i = 1; i < propertyPathParts.length; i++ ) {
|
for ( int i = 1; i < propertyPathParts.length; i++ ) {
|
||||||
if ( ! ( subPart instanceof ModelPartContainer ) ) {
|
if ( ! ( subPart instanceof ModelPartContainer ) ) {
|
||||||
throw new MappingException(
|
throw new MappingException(
|
||||||
"Non-terminal property path [" + navigablePath.getFullPath()
|
String.format(
|
||||||
+ " did not reference FetchableContainer"
|
Locale.ROOT,
|
||||||
|
"Non-terminal property path did not reference FetchableContainer - %s ",
|
||||||
|
navigablePath
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
navigablePath = navigablePath.append( propertyPathParts[ i ] );
|
navigablePath = navigablePath.append( propertyPathParts[ i ] );
|
||||||
|
|
|
@ -899,8 +899,8 @@ public class ToOneAttributeMapping
|
||||||
final NavigablePath parentPath = grandparentNavigablePath.getParent();
|
final NavigablePath parentPath = grandparentNavigablePath.getParent();
|
||||||
// This can be null for a collection loader
|
// This can be null for a collection loader
|
||||||
if ( parentPath == null ) {
|
if ( parentPath == null ) {
|
||||||
return grandparentNavigablePath.getFullPath().equals(
|
return grandparentNavigablePath.equals(
|
||||||
entityMappingType.findSubPart( bidirectionalAttributeName ).getNavigableRole().getFullPath()
|
entityMappingType.findSubPart( bidirectionalAttributeName ).getNavigableRole()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -78,8 +78,8 @@ public class QualifiedJoinPredicatePathConsumer extends BasicDotIdentifierConsum
|
||||||
String.format(
|
String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"SqmQualifiedJoin predicate referred to SqmRoot [`%s`] other than the join's root [`%s`]",
|
"SqmQualifiedJoin predicate referred to SqmRoot [`%s`] other than the join's root [`%s`]",
|
||||||
pathRoot.getNavigablePath().getFullPath(),
|
pathRoot.getNavigablePath(),
|
||||||
sqmJoin.getNavigablePath().getFullPath()
|
sqmJoin.getNavigablePath()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -110,8 +110,8 @@ public class QualifiedJoinPredicatePathConsumer extends BasicDotIdentifierConsum
|
||||||
String.format(
|
String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"SqmQualifiedJoin predicate referred to SqmRoot [`%s`] other than the join's root [`%s`]",
|
"SqmQualifiedJoin predicate referred to SqmRoot [`%s`] other than the join's root [`%s`]",
|
||||||
pathRoot.getNavigablePath().getFullPath(),
|
pathRoot.getNavigablePath(),
|
||||||
sqmJoin.getNavigablePath().getFullPath()
|
sqmJoin.getNavigablePath()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2291,7 +2291,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
throw new NotYetImplementedFor6Exception( "Path continuation from `id()` reference not yet implemented" );
|
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
|
@Override
|
||||||
|
@ -2312,7 +2312,8 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
throw new SemanticException(
|
throw new SemanticException(
|
||||||
String.format(
|
String.format(
|
||||||
"Path '%s' resolved to entity type '%s' which does not define a version",
|
"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<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
return sqmPath.get( versionAttribute );
|
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
|
@Override
|
||||||
|
@ -2341,7 +2342,8 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
throw new SemanticException(
|
throw new SemanticException(
|
||||||
String.format(
|
String.format(
|
||||||
"Path '%s' resolved to entity type '%s' which does not define a natural id",
|
"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<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
throw new SemanticException(
|
throw new SemanticException(
|
||||||
String.format(
|
String.format(
|
||||||
"Path '%s' resolved to entity type '%s' which defines multiple natural ids",
|
"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<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
return sqmPath.get( naturalIdAttribute );
|
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
|
@Override
|
||||||
|
@ -2381,7 +2384,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
String.format(
|
String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"`%s` used in `fk()` only supported for to-one mappings, but found `%s`",
|
"`%s` used in `fk()` only supported for to-one mappings, but found `%s`",
|
||||||
sqmPath.getNavigablePath().getFullPath(),
|
sqmPath.getNavigablePath(),
|
||||||
toOneReference
|
toOneReference
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class SqmPathRegistryImpl implements SqmPathRegistry {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(SqmPath<?> sqmPath) {
|
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:
|
// Generally we:
|
||||||
// 1) add the path to the path-by-path map
|
// 1) add the path to the path-by-path map
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class UnknownPathException extends SemanticException {
|
||||||
"Could not resolve path `%s` relative to %s (%s)",
|
"Could not resolve path `%s` relative to %s (%s)",
|
||||||
name,
|
name,
|
||||||
base.getReferencedPathSource().getSqmPathType().getTypeName(),
|
base.getReferencedPathSource().getSqmPathType().getTypeName(),
|
||||||
base.getNavigablePath().getFullPath()
|
base.getNavigablePath()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,7 +283,7 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
||||||
processStanza(
|
processStanza(
|
||||||
"delete",
|
"delete",
|
||||||
() -> {
|
() -> {
|
||||||
logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath().getFullPath() );
|
logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath() );
|
||||||
visitWhereClause( statement.getWhereClause() );
|
visitWhereClause( statement.getWhereClause() );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -298,7 +298,7 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
||||||
processStanza(
|
processStanza(
|
||||||
"insert",
|
"insert",
|
||||||
() -> {
|
() -> {
|
||||||
logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath().getFullPath() );
|
logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath() );
|
||||||
processStanza(
|
processStanza(
|
||||||
"into",
|
"into",
|
||||||
() -> statement.getInsertionTargetPaths().forEach( sqmPath -> sqmPath.accept( this ) )
|
() -> statement.getInsertionTargetPaths().forEach( sqmPath -> sqmPath.accept( this ) )
|
||||||
|
@ -317,7 +317,7 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
||||||
processStanza(
|
processStanza(
|
||||||
"insert",
|
"insert",
|
||||||
() -> {
|
() -> {
|
||||||
logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath().getFullPath() );
|
logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath() );
|
||||||
processStanza(
|
processStanza(
|
||||||
"into",
|
"into",
|
||||||
() -> statement.getInsertionTargetPaths().forEach( sqmPath -> sqmPath.accept( this ) )
|
() -> statement.getInsertionTargetPaths().forEach( sqmPath -> sqmPath.accept( this ) )
|
||||||
|
@ -361,7 +361,7 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
||||||
processStanza(
|
processStanza(
|
||||||
statement.isVersioned() ? "update versioned" : "update",
|
statement.isVersioned() ? "update versioned" : "update",
|
||||||
() -> {
|
() -> {
|
||||||
logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath().getFullPath() );
|
logWithIndentation( "[target = %s]", statement.getTarget().getNavigablePath() );
|
||||||
|
|
||||||
visitSetClause( statement.getSetClause() );
|
visitSetClause( statement.getSetClause() );
|
||||||
|
|
||||||
|
@ -495,7 +495,7 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
||||||
public Object visitRootPath(SqmRoot sqmRoot) {
|
public Object visitRootPath(SqmRoot sqmRoot) {
|
||||||
processStanza(
|
processStanza(
|
||||||
"root",
|
"root",
|
||||||
'`' + sqmRoot.getNavigablePath().getFullPath() + '`',
|
"`" + sqmRoot.getNavigablePath() + "`",
|
||||||
() -> processJoins( sqmRoot )
|
() -> processJoins( sqmRoot )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -517,7 +517,7 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
||||||
public Object visitCrossJoin(SqmCrossJoin joinedFromElement) {
|
public Object visitCrossJoin(SqmCrossJoin joinedFromElement) {
|
||||||
processStanza(
|
processStanza(
|
||||||
"cross",
|
"cross",
|
||||||
'`' + joinedFromElement.getNavigablePath().getFullPath() + '`',
|
"`" + joinedFromElement.getNavigablePath() + "`",
|
||||||
() -> processJoins( joinedFromElement )
|
() -> processJoins( joinedFromElement )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -528,7 +528,7 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
||||||
public Object visitPluralPartJoin(SqmPluralPartJoin<?, ?> joinedFromElement) {
|
public Object visitPluralPartJoin(SqmPluralPartJoin<?, ?> joinedFromElement) {
|
||||||
processStanza(
|
processStanza(
|
||||||
"plural-part",
|
"plural-part",
|
||||||
'`' + joinedFromElement.getNavigablePath().getFullPath() + '`',
|
"`" + joinedFromElement.getNavigablePath() + "`",
|
||||||
() -> processJoins( joinedFromElement )
|
() -> processJoins( joinedFromElement )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -552,12 +552,12 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
||||||
@Override
|
@Override
|
||||||
public Object visitQualifiedEntityJoin(SqmEntityJoin joinedFromElement) {
|
public Object visitQualifiedEntityJoin(SqmEntityJoin joinedFromElement) {
|
||||||
if ( inJoinPredicate ) {
|
if ( inJoinPredicate ) {
|
||||||
logWithIndentation( "-> [joined-path] - `%s`", joinedFromElement.getNavigablePath().getFullPath() );
|
logWithIndentation( "-> [joined-path] - `%s`", joinedFromElement.getNavigablePath() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
processStanza(
|
processStanza(
|
||||||
"entity",
|
"entity",
|
||||||
'`' + joinedFromElement.getNavigablePath().getFullPath() + '`',
|
"`" + joinedFromElement.getNavigablePath() + "`",
|
||||||
() -> {
|
() -> {
|
||||||
processJoinPredicate( joinedFromElement );
|
processJoinPredicate( joinedFromElement );
|
||||||
processJoins( joinedFromElement );
|
processJoins( joinedFromElement );
|
||||||
|
@ -570,12 +570,12 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
||||||
@Override
|
@Override
|
||||||
public Object visitQualifiedAttributeJoin(SqmAttributeJoin joinedFromElement) {
|
public Object visitQualifiedAttributeJoin(SqmAttributeJoin joinedFromElement) {
|
||||||
if ( inJoinPredicate ) {
|
if ( inJoinPredicate ) {
|
||||||
logWithIndentation( "-> [joined-path] - `%s`", joinedFromElement.getNavigablePath().getFullPath() );
|
logWithIndentation( "-> [joined-path] - `%s`", joinedFromElement.getNavigablePath() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
processStanza(
|
processStanza(
|
||||||
"attribute",
|
"attribute",
|
||||||
'`' + joinedFromElement.getNavigablePath().getFullPath() + '`',
|
"`" + joinedFromElement.getNavigablePath() + "`",
|
||||||
() -> {
|
() -> {
|
||||||
logIndented( "[fetched = " + joinedFromElement.isFetched() + ']' );
|
logIndented( "[fetched = " + joinedFromElement.isFetched() + ']' );
|
||||||
|
|
||||||
|
@ -589,56 +589,56 @@ public class SqmTreePrinter implements SemanticQueryWalker<Object> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitBasicValuedPath(SqmBasicValuedSimplePath path) {
|
public Object visitBasicValuedPath(SqmBasicValuedSimplePath path) {
|
||||||
logWithIndentation( "-> [basic-path] - `%s`", path.getNavigablePath().getFullPath() );
|
logWithIndentation( "-> [basic-path] - `%s`", path.getNavigablePath() );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitEmbeddableValuedPath(SqmEmbeddedValuedSimplePath path) {
|
public Object visitEmbeddableValuedPath(SqmEmbeddedValuedSimplePath path) {
|
||||||
logWithIndentation( "-> [embedded-path] - `%s`", path.getNavigablePath().getFullPath() );
|
logWithIndentation( "-> [embedded-path] - `%s`", path.getNavigablePath() );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitAnyValuedValuedPath(SqmAnyValuedSimplePath<?> path) {
|
public Object visitAnyValuedValuedPath(SqmAnyValuedSimplePath<?> path) {
|
||||||
logWithIndentation( "-> [any-path] - `%s`", path.getNavigablePath().getFullPath() );
|
logWithIndentation( "-> [any-path] - `%s`", path.getNavigablePath() );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitNonAggregatedCompositeValuedPath(NonAggregatedCompositeSimplePath<?> path) {
|
public Object visitNonAggregatedCompositeValuedPath(NonAggregatedCompositeSimplePath<?> path) {
|
||||||
logWithIndentation( "-> [non-aggregated-composite-path] - `%s`", path.getNavigablePath().getFullPath() );
|
logWithIndentation( "-> [non-aggregated-composite-path] - `%s`", path.getNavigablePath() );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitFkExpression(SqmFkExpression<?> fkExpression) {
|
public Object visitFkExpression(SqmFkExpression<?> fkExpression) {
|
||||||
logWithIndentation( "-> [fk-ref] - `%s`", fkExpression.getToOnePath().getNavigablePath().getFullPath() );
|
logWithIndentation( "-> [fk-ref] - `%s`", fkExpression.getToOnePath().getNavigablePath() );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitSelfInterpretingSqmPath(SelfInterpretingSqmPath<?> sqmPath) {
|
public Object visitSelfInterpretingSqmPath(SelfInterpretingSqmPath<?> sqmPath) {
|
||||||
logWithIndentation( "-> [self-interpreting-path] - `%s`", sqmPath.getNavigablePath().getFullPath() );
|
logWithIndentation( "-> [self-interpreting-path] - `%s`", sqmPath.getNavigablePath() );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitEntityValuedPath(SqmEntityValuedSimplePath path) {
|
public Object visitEntityValuedPath(SqmEntityValuedSimplePath path) {
|
||||||
logWithIndentation( "-> [entity-path] - `%s`", path.getNavigablePath().getFullPath() );
|
logWithIndentation( "-> [entity-path] - `%s`", path.getNavigablePath() );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitPluralValuedPath(SqmPluralValuedSimplePath path) {
|
public Object visitPluralValuedPath(SqmPluralValuedSimplePath path) {
|
||||||
logWithIndentation( "-> [plural-path] - `%s`", path.getNavigablePath().getFullPath() );
|
logWithIndentation( "-> [plural-path] - `%s`", path.getNavigablePath() );
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class BasicValuedPathInterpretation<T> 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(
|
final TableReference tableReference = tableGroup.resolveTableReference(
|
||||||
|
@ -148,7 +148,7 @@ public class BasicValuedPathInterpretation<T> extends AbstractSqmPathInterpretat
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "BasicValuedPathInterpretation(" + getNavigablePath().getFullPath() + ')';
|
return "BasicValuedPathInterpretation(" + getNavigablePath() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class EmbeddableValuedPathInterpretation<T> extends AbstractSqmPathInterp
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "EmbeddableValuedPathInterpretation(" + getNavigablePath().getFullPath() + ')';
|
return "EmbeddableValuedPathInterpretation(" + getNavigablePath() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -434,7 +434,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
|
||||||
"Passed attribute name [%s] did not correspond to a collection (bag) reference [%s] relative to %s",
|
"Passed attribute name [%s] did not correspond to a collection (bag) reference [%s] relative to %s",
|
||||||
attributeName,
|
attributeName,
|
||||||
joinedPathSource,
|
joinedPathSource,
|
||||||
getNavigablePath().getFullPath()
|
getNavigablePath()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -465,7 +465,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
|
||||||
"Passed attribute name [%s] did not correspond to a collection (set) reference [%s] relative to %s",
|
"Passed attribute name [%s] did not correspond to a collection (set) reference [%s] relative to %s",
|
||||||
attributeName,
|
attributeName,
|
||||||
joinedPathSource,
|
joinedPathSource,
|
||||||
getNavigablePath().getFullPath()
|
getNavigablePath()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -496,7 +496,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
|
||||||
"Passed attribute name [%s] did not correspond to a collection (list) reference [%s] relative to %s",
|
"Passed attribute name [%s] did not correspond to a collection (list) reference [%s] relative to %s",
|
||||||
attributeName,
|
attributeName,
|
||||||
joinedPathSource,
|
joinedPathSource,
|
||||||
getNavigablePath().getFullPath()
|
getNavigablePath()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -527,7 +527,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
|
||||||
"Passed attribute name [%s] did not correspond to a collection (map) reference [%s] relative to %s",
|
"Passed attribute name [%s] did not correspond to a collection (map) reference [%s] relative to %s",
|
||||||
attributeName,
|
attributeName,
|
||||||
joinedPathSource,
|
joinedPathSource,
|
||||||
getNavigablePath().getFullPath()
|
getNavigablePath()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -659,7 +659,7 @@ public abstract class AbstractSqmFrom<O,T> extends AbstractSqmPath<T> implements
|
||||||
"Passed attribute [%s] did not correspond to a joinable reference [%s] relative to %s",
|
"Passed attribute [%s] did not correspond to a joinable reference [%s] relative to %s",
|
||||||
joinedPathSource.getPathName(),
|
joinedPathSource.getPathName(),
|
||||||
joinedPathSource,
|
joinedPathSource,
|
||||||
getNavigablePath().getFullPath()
|
getNavigablePath()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,6 +195,6 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getClass().getSimpleName() + "(" + navigablePath.getFullPath() + ")";
|
return getClass().getSimpleName() + "(" + navigablePath + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class SqmPluralPartJoin<O,T> extends AbstractSqmJoin<O,T> implements SqmQ
|
||||||
return String.format(
|
return String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"SqmPluralPartJoin(%s : %s)",
|
"SqmPluralPartJoin(%s : %s)",
|
||||||
getNavigablePath().getFullPath(),
|
getNavigablePath(),
|
||||||
getReferencedPathSource().getPathName()
|
getReferencedPathSource().getPathName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ public class SqmSingularJoin<O,T> extends AbstractSqmAttributeJoin<O,T> {
|
||||||
return String.format(
|
return String.format(
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"SqmSingularJoin(%s : %s)",
|
"SqmSingularJoin(%s : %s)",
|
||||||
getNavigablePath().getFullPath(),
|
getNavigablePath(),
|
||||||
getReferencedPathSource().getPathName()
|
getReferencedPathSource().getPathName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,9 @@ public interface DotIdentifierSequence {
|
||||||
/**
|
/**
|
||||||
* The full sequence text. E.g., given the sequence `a.b.c`,
|
* The full sequence text. E.g., given the sequence `a.b.c`,
|
||||||
* this returns `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();
|
String getFullPath();
|
||||||
|
|
||||||
|
|
|
@ -24,62 +24,79 @@ public class EntityIdentifierNavigablePath extends NavigablePath {
|
||||||
this.identifierAttributeName = identifierAttributeName;
|
this.identifierAttributeName = identifierAttributeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getIdentifierAttributeName() {
|
||||||
|
return identifierAttributeName;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getLocalName() {
|
public String getLocalName() {
|
||||||
return EntityIdentifierMapping.ROLE_LOCAL_NAME;
|
return EntityIdentifierMapping.ROLE_LOCAL_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
protected boolean localNamesMatch(DotIdentifierSequence otherPath) {
|
||||||
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();
|
final String otherLocalName = otherPath.getLocalName();
|
||||||
|
|
||||||
return otherLocalName.equals( getLocalName() )
|
return otherLocalName.equals( getLocalName() )
|
||||||
|| otherLocalName.equals( identifierAttributeName );
|
|| 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 );
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.spi;
|
package org.hibernate.spi;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.hibernate.Incubating;
|
import org.hibernate.Incubating;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
@ -25,41 +26,9 @@ public class NavigablePath implements DotIdentifierSequence, Serializable {
|
||||||
private final NavigablePath parent;
|
private final NavigablePath parent;
|
||||||
private final String localName;
|
private final String localName;
|
||||||
private final String alias;
|
private final String alias;
|
||||||
|
|
||||||
private final String identifierForTableGroup;
|
private final String identifierForTableGroup;
|
||||||
|
private final FullPathCalculator fullPathCalculator;
|
||||||
private final String fullPath;
|
private final int hashCode;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public NavigablePath(String localName) {
|
public NavigablePath(String localName) {
|
||||||
this( localName, null );
|
this( localName, null );
|
||||||
|
@ -67,88 +36,69 @@ public class NavigablePath implements DotIdentifierSequence, Serializable {
|
||||||
|
|
||||||
public NavigablePath(String rootName, String alias) {
|
public NavigablePath(String rootName, String alias) {
|
||||||
this.parent = null;
|
this.parent = null;
|
||||||
this.alias = StringHelper.nullIfEmpty( alias );
|
this.alias = alias = StringHelper.nullIfEmpty( alias );
|
||||||
this.localName = rootName;
|
this.localName = rootName;
|
||||||
this.identifierForTableGroup = 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) {
|
public NavigablePath(NavigablePath parent, String navigableName) {
|
||||||
alias = StringHelper.nullIfEmpty( alias );
|
this( parent, navigableName, null );
|
||||||
final String navigableName = alias == null
|
}
|
||||||
? property
|
|
||||||
: property + '(' + alias + ')';
|
public NavigablePath(NavigablePath parent, String localName, String alias) {
|
||||||
|
assert parent != null;
|
||||||
|
|
||||||
this.parent = parent;
|
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.
|
// the _identifierMapper is a "hidden property" on entities with composite keys.
|
||||||
// concatenating it will prevent the path from correctly being used to look up
|
// concatenating it will prevent the path from correctly being used to look up
|
||||||
// various things such as criteria paths and fetch profile association paths
|
// various things such as criteria paths and fetch profile association paths
|
||||||
if ( IDENTIFIER_MAPPER_PROPERTY.equals( navigableName ) ) {
|
if ( IDENTIFIER_MAPPER_PROPERTY.equals( localName ) ) {
|
||||||
this.fullPath = parent != null ? parent.getFullPath() : "";
|
|
||||||
this.localName = "";
|
this.localName = "";
|
||||||
identifierForTableGroup = parent != null ? parent.getFullPath() : "";
|
this.identifierForTableGroup = parent.getFullPath();
|
||||||
|
this.fullPathCalculator = NavigablePath::calculateIdMapperFullPath;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.localName = property;
|
this.localName = localName;
|
||||||
if ( parent != null ) {
|
this.identifierForTableGroup = StringHelper.isEmpty( parent.getIdentifierForTableGroup() )
|
||||||
final String parentFullPath = parent.getFullPath();
|
? aliasedLocalName
|
||||||
this.fullPath = StringHelper.isEmpty( parentFullPath )
|
: parent.getIdentifierForTableGroup() + "." + localName;
|
||||||
? navigableName
|
this.fullPathCalculator = NavigablePath::calculateNormalFullPath;
|
||||||
: parentFullPath + "." + navigableName;
|
|
||||||
this.identifierForTableGroup = StringHelper.isEmpty( parent.getIdentifierForTableGroup() )
|
|
||||||
? navigableName
|
|
||||||
: parent.getIdentifierForTableGroup() + "." + property;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.fullPath = navigableName;
|
|
||||||
this.identifierForTableGroup = property;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public NavigablePath() {
|
|
||||||
this( "" );
|
|
||||||
}
|
|
||||||
|
|
||||||
public NavigablePath(
|
public NavigablePath(
|
||||||
NavigablePath parent,
|
NavigablePath parent,
|
||||||
String fullPath,
|
|
||||||
String localName,
|
String localName,
|
||||||
String identifierForTableGroup) {
|
String alias,
|
||||||
|
String identifierForTableGroup,
|
||||||
|
FullPathCalculator fullPathCalculator,
|
||||||
|
int hashCode) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.alias = null;
|
|
||||||
this.fullPath = fullPath;
|
|
||||||
this.localName = localName;
|
this.localName = localName;
|
||||||
|
this.hashCode = hashCode;
|
||||||
|
this.alias = StringHelper.nullIfEmpty( alias );
|
||||||
this.identifierForTableGroup = identifierForTableGroup;
|
this.identifierForTableGroup = identifierForTableGroup;
|
||||||
|
this.fullPathCalculator = fullPathCalculator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NavigablePath treatAs(String entityName) {
|
@Override
|
||||||
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 );
|
|
||||||
}
|
|
||||||
|
|
||||||
public NavigablePath getParent() {
|
public NavigablePath getParent() {
|
||||||
return parent instanceof TreatedNavigablePath ? parent.getParent() : parent;
|
return parent instanceof TreatedNavigablePath ? parent.getParent() : parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NavigablePath getRealParent() {
|
@Override
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLocalName() {
|
public String getLocalName() {
|
||||||
return localName;
|
return localName;
|
||||||
}
|
}
|
||||||
|
@ -162,17 +112,75 @@ public class NavigablePath implements DotIdentifierSequence, Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIdentifierForTableGroup() {
|
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;
|
return identifierForTableGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFullPath() {
|
@Override
|
||||||
return fullPath;
|
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) {
|
public boolean isParent(NavigablePath navigablePath) {
|
||||||
while ( navigablePath != null ) {
|
while ( navigablePath != null ) {
|
||||||
if ( this.equals( navigablePath.getParent() ) ) {
|
if ( this.equals( navigablePath.getParent() ) ) {
|
||||||
|
@ -183,45 +191,49 @@ public class NavigablePath implements DotIdentifierSequence, Serializable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFullPath() {
|
||||||
|
return fullPathCalculator.calculateFullPath( parent, localName, alias );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return fullPath;
|
return getFullPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public int hashCode() {
|
* Effectively a tri-function
|
||||||
return fullPath.hashCode();
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
protected interface FullPathCalculator extends Serializable {
|
||||||
|
String calculateFullPath(NavigablePath parent, String localName, String alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public boolean equals(Object other) {
|
* The pattern used for root NavigablePaths
|
||||||
if ( this == other ) {
|
*/
|
||||||
return true;
|
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;
|
* The normal pattern used for the "full path"
|
||||||
return otherPath.equals( this );
|
*/
|
||||||
}
|
private static String calculateNormalFullPath(NavigablePath parent, String localName, String alias) {
|
||||||
|
assert parent != null;
|
||||||
|
|
||||||
if ( ! ( other instanceof NavigablePath ) ) {
|
final String parentFullPath = parent.getFullPath();
|
||||||
return false;
|
final String baseFullPath = StringHelper.isEmpty( parentFullPath )
|
||||||
}
|
? localName
|
||||||
|
: parentFullPath + "." + localName;
|
||||||
|
return alias == null ? baseFullPath : baseFullPath + "(" + alias + ")";
|
||||||
|
}
|
||||||
|
|
||||||
final NavigablePath otherPath = (NavigablePath) other;
|
/**
|
||||||
|
* Pattern used for `_identifierMapper`
|
||||||
// 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
|
protected static String calculateIdMapperFullPath(NavigablePath parent, String localName, String alias) {
|
||||||
// an identifier at some level - the actual EntityIdentifierNavigablePath
|
return parent != null ? parent.getFullPath() : "";
|
||||||
// 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() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,21 @@ public class TreatedNavigablePath extends NavigablePath {
|
||||||
public TreatedNavigablePath(NavigablePath parent, String entityTypeName, String alias) {
|
public TreatedNavigablePath(NavigablePath parent, String entityTypeName, String alias) {
|
||||||
super(
|
super(
|
||||||
parent,
|
parent,
|
||||||
alias == null ? "treat(" + parent.getFullPath() + " as " + entityTypeName + ")"
|
|
||||||
: "treat(" + parent.getFullPath() + " as " + entityTypeName + ")(" + alias + ")",
|
|
||||||
entityTypeName,
|
entityTypeName,
|
||||||
"treat(" + parent.getFullPath() + " as " + entityTypeName + ")"
|
alias,
|
||||||
|
"treat(" + parent + " as " + entityTypeName + ")",
|
||||||
|
TreatedNavigablePath::calculateTreatedFullPath,
|
||||||
|
1
|
||||||
);
|
);
|
||||||
assert !( parent instanceof TreatedNavigablePath );
|
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
|
@Override
|
||||||
public NavigablePath treatAs(String entityName) {
|
public NavigablePath treatAs(String entityName) {
|
||||||
return new TreatedNavigablePath( getRealParent(), entityName );
|
return new TreatedNavigablePath( getRealParent(), entityName );
|
||||||
|
@ -41,25 +48,25 @@ public class TreatedNavigablePath extends NavigablePath {
|
||||||
return new TreatedNavigablePath( getRealParent(), entityName, alias );
|
return new TreatedNavigablePath( getRealParent(), entityName, alias );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public int hashCode() {
|
// public int hashCode() {
|
||||||
return getFullPath().hashCode();
|
// return getFullPath().hashCode();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
public boolean equals(Object other) {
|
// public boolean equals(Object other) {
|
||||||
if ( other == null ) {
|
// if ( other == null ) {
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if ( other == this ) {
|
// if ( other == this ) {
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if ( ! ( other instanceof NavigablePath ) ) {
|
// if ( ! ( other instanceof NavigablePath ) ) {
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return getFullPath().equals( ( (NavigablePath) other ).getFullPath() );
|
// return getFullPath().equals( ( (NavigablePath) other ).getFullPath() );
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public abstract class AbstractColumnReferenceQualifier implements ColumnReferenc
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"Unable to determine TableReference (`%s`) for `%s`",
|
"Unable to determine TableReference (`%s`) for `%s`",
|
||||||
tableExpression,
|
tableExpression,
|
||||||
navigablePath.getFullPath()
|
navigablePath
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ public abstract class DerivedTableReference extends AbstractTableReference {
|
||||||
boolean allowFkOptimization) {
|
boolean allowFkOptimization) {
|
||||||
throw new UnknownTableReferenceException(
|
throw new UnknownTableReferenceException(
|
||||||
tableExpression,
|
tableExpression,
|
||||||
"TableReferences cannot be resolved relative to DerivedTableReferences - `" + tableExpression + "` : " + navigablePath.getFullPath()
|
"TableReferences cannot be resolved relative to DerivedTableReferences - `" + tableExpression + "` : " + navigablePath
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,7 +252,7 @@ public class LazyTableGroup extends DelegatingTableGroup {
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"Unable to determine TableReference (`%s`) for `%s`",
|
"Unable to determine TableReference (`%s`) for `%s`",
|
||||||
tableExpression,
|
tableExpression,
|
||||||
navigablePath.getFullPath()
|
navigablePath
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ public class MappedByTableGroup extends DelegatingTableGroup implements VirtualT
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"Unable to determine TableReference (`%s`) for `%s`",
|
"Unable to determine TableReference (`%s`) for `%s`",
|
||||||
tableExpression,
|
tableExpression,
|
||||||
navigablePath.getFullPath()
|
navigablePath
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class NamedTableReference extends AbstractTableReference {
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"Unable to determine TableReference (`%s`) for `%s`",
|
"Unable to determine TableReference (`%s`) for `%s`",
|
||||||
tableExpression,
|
tableExpression,
|
||||||
navigablePath.getFullPath()
|
navigablePath
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class UnionTableReference extends NamedTableReference {
|
||||||
Locale.ROOT,
|
Locale.ROOT,
|
||||||
"Unable to determine TableReference (`%s`) for `%s`",
|
"Unable to determine TableReference (`%s`) for `%s`",
|
||||||
tableExpression,
|
tableExpression,
|
||||||
navigablePath.getFullPath()
|
navigablePath
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,7 +290,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
|
||||||
EntityLoadingLogging.ENTITY_LOADING_LOGGER.tracef(
|
EntityLoadingLogging.ENTITY_LOADING_LOGGER.tracef(
|
||||||
"(%s) Beginning Initializer#resolveKey process for entity : %s",
|
"(%s) Beginning Initializer#resolveKey process for entity : %s",
|
||||||
StringHelper.collapse( this.getClass().getName() ),
|
StringHelper.collapse( this.getClass().getName() ),
|
||||||
getNavigablePath().getFullPath()
|
getNavigablePath()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,6 @@ public class EntityResultInitializer extends AbstractEntityInitializer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return CONCRETE_NAME + "(" + getNavigablePath().getFullPath() + ")";
|
return CONCRETE_NAME + "(" + getNavigablePath() + ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ public class ResultsHelper {
|
||||||
initializerMap.forEach( (navigablePath, initializer) -> {
|
initializerMap.forEach( (navigablePath, initializer) -> {
|
||||||
ResultsLogger.RESULTS_MESSAGE_LOGGER.debugf(
|
ResultsLogger.RESULTS_MESSAGE_LOGGER.debugf(
|
||||||
" %s -> %s@%s (%s)",
|
" %s -> %s@%s (%s)",
|
||||||
navigablePath.getFullPath(),
|
navigablePath,
|
||||||
initializer,
|
initializer,
|
||||||
initializer.hashCode(),
|
initializer.hashCode(),
|
||||||
initializer.getInitializedPart()
|
initializer.getInitializedPart()
|
||||||
|
|
Loading…
Reference in New Issue