HHH-15132 - Improvements for NavigablePath
Begin breaking down "full path"
This commit is contained in:
parent
73153be99d
commit
f474449e7d
|
@ -667,14 +667,14 @@ public class EntityCollectionPart
|
||||||
NavigablePath path = np.getParent();
|
NavigablePath path = np.getParent();
|
||||||
// Fast path
|
// Fast path
|
||||||
if ( navigablePath.equals( path ) ) {
|
if ( navigablePath.equals( path ) ) {
|
||||||
return targetKeyPropertyNames.contains( np.getUnaliasedLocalName() )
|
return targetKeyPropertyNames.contains( np.getLocalName() )
|
||||||
&& fkDescriptor.getKeyTable().equals( tableExpression );
|
&& fkDescriptor.getKeyTable().equals( tableExpression );
|
||||||
}
|
}
|
||||||
final StringBuilder sb = new StringBuilder( np.getFullPath().length() );
|
final StringBuilder sb = new StringBuilder( np.getFullPath().length() );
|
||||||
sb.append( np.getUnaliasedLocalName() );
|
sb.append( np.getLocalName() );
|
||||||
while ( path != null && !navigablePath.equals( path ) ) {
|
while ( path != null && !navigablePath.equals( path ) ) {
|
||||||
sb.insert( 0, '.' );
|
sb.insert( 0, '.' );
|
||||||
sb.insert( 0, path.getUnaliasedLocalName() );
|
sb.insert( 0, path.getLocalName() );
|
||||||
path = path.getParent();
|
path = path.getParent();
|
||||||
}
|
}
|
||||||
return navigablePath.equals( path )
|
return navigablePath.equals( path )
|
||||||
|
|
|
@ -202,7 +202,7 @@ public class PluralAttributeMappingImpl
|
||||||
// then we say this is bidirectional, given that this is only invoked for model parts of the collection elements
|
// then we say this is bidirectional, given that this is only invoked for model parts of the collection elements
|
||||||
return fkDescriptor.getTargetPart() == modelPart.getForeignKeyDescriptor().getTargetPart();
|
return fkDescriptor.getTargetPart() == modelPart.getForeignKeyDescriptor().getTargetPart();
|
||||||
}
|
}
|
||||||
return fetchablePath.getUnaliasedLocalName().endsWith( bidirectionalAttributeName );
|
return fetchablePath.getLocalName().endsWith( bidirectionalAttributeName );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
|
|
@ -748,8 +748,8 @@ public class ToOneAttributeMapping
|
||||||
private Key key;
|
private Key key;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if ( parentNavigablePath.getUnaliasedLocalName().equals( ForeignKeyDescriptor.PART_NAME )
|
if ( parentNavigablePath.getLocalName().equals( ForeignKeyDescriptor.PART_NAME )
|
||||||
|| parentNavigablePath.getUnaliasedLocalName().equals( ForeignKeyDescriptor.TARGET_PART_NAME ) ) {
|
|| parentNavigablePath.getLocalName().equals( ForeignKeyDescriptor.TARGET_PART_NAME ) ) {
|
||||||
// todo (6.0): maybe it's better to have a flag in creation state that marks if we are building a circular fetch domain result already to skip this?
|
// todo (6.0): maybe it's better to have a flag in creation state that marks if we are building a circular fetch domain result already to skip this?
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -893,9 +893,9 @@ public class ToOneAttributeMapping
|
||||||
parent.getFullPath() = "Mother.biologicalChild"
|
parent.getFullPath() = "Mother.biologicalChild"
|
||||||
*/
|
*/
|
||||||
final NavigablePath grandparentNavigablePath = parentNavigablePath.getParent();
|
final NavigablePath grandparentNavigablePath = parentNavigablePath.getParent();
|
||||||
if ( parentNavigablePath.getUnaliasedLocalName().equals( CollectionPart.Nature.ELEMENT.getName() )
|
if ( parentNavigablePath.getLocalName().equals( CollectionPart.Nature.ELEMENT.getName() )
|
||||||
&& grandparentNavigablePath != null
|
&& grandparentNavigablePath != null
|
||||||
&& grandparentNavigablePath.getUnaliasedLocalName().equals( bidirectionalAttributeName ) ) {
|
&& grandparentNavigablePath.getLocalName().equals( bidirectionalAttributeName ) ) {
|
||||||
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 ) {
|
||||||
|
@ -915,13 +915,13 @@ public class ToOneAttributeMapping
|
||||||
}
|
}
|
||||||
// If we have a parent, we ensure that the parent is the same as the attribute name
|
// If we have a parent, we ensure that the parent is the same as the attribute name
|
||||||
else {
|
else {
|
||||||
return parentPath.getUnaliasedLocalName().equals( navigableRole.getLocalName() );
|
return parentPath.getLocalName().equals( navigableRole.getLocalName() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return parentNavigablePath.getUnaliasedLocalName().equals( bidirectionalAttributeName );
|
return parentNavigablePath.getLocalName().equals( bidirectionalAttributeName );
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBidirectionalAttributeName(){
|
public String getBidirectionalAttributeName(){
|
||||||
|
@ -944,7 +944,7 @@ public class ToOneAttributeMapping
|
||||||
referencedNavigablePath = parentNavigablePath;
|
referencedNavigablePath = parentNavigablePath;
|
||||||
hasBidirectionalFetchParent = true;
|
hasBidirectionalFetchParent = true;
|
||||||
}
|
}
|
||||||
else if ( CollectionPart.Nature.fromNameExact( parentNavigablePath.getUnaliasedLocalName() ) != null ) {
|
else if ( CollectionPart.Nature.fromNameExact( parentNavigablePath.getLocalName() ) != null ) {
|
||||||
referencedNavigablePath = parentNavigablePath.getParent().getParent();
|
referencedNavigablePath = parentNavigablePath.getParent().getParent();
|
||||||
hasBidirectionalFetchParent = fetchParent instanceof Fetch
|
hasBidirectionalFetchParent = fetchParent instanceof Fetch
|
||||||
&& ( (Fetch) fetchParent ).getFetchParent() instanceof Fetch;
|
&& ( (Fetch) fetchParent ).getFetchParent() instanceof Fetch;
|
||||||
|
@ -1007,7 +1007,7 @@ public class ToOneAttributeMapping
|
||||||
// So we create a delayed fetch, as we are sure to find the entity in the PC
|
// So we create a delayed fetch, as we are sure to find the entity in the PC
|
||||||
final FromClauseAccess fromClauseAccess = creationState.getSqlAstCreationState().getFromClauseAccess();
|
final FromClauseAccess fromClauseAccess = creationState.getSqlAstCreationState().getFromClauseAccess();
|
||||||
final NavigablePath realParent;
|
final NavigablePath realParent;
|
||||||
if ( CollectionPart.Nature.fromNameExact( parentNavigablePath.getUnaliasedLocalName() ) != null ) {
|
if ( CollectionPart.Nature.fromNameExact( parentNavigablePath.getLocalName() ) != null ) {
|
||||||
realParent = parentNavigablePath.getParent();
|
realParent = parentNavigablePath.getParent();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1386,7 +1386,7 @@ public class ToOneAttributeMapping
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( CollectionPart.Nature.ELEMENT.getName().equals( parentTableGroup.getNavigablePath().getUnaliasedLocalName() ) ) {
|
if ( CollectionPart.Nature.ELEMENT.getName().equals( parentTableGroup.getNavigablePath().getLocalName() ) ) {
|
||||||
final PluralTableGroup pluralTableGroup = (PluralTableGroup) fromClauseAccess.findTableGroup(
|
final PluralTableGroup pluralTableGroup = (PluralTableGroup) fromClauseAccess.findTableGroup(
|
||||||
parentTableGroup.getNavigablePath().getParent()
|
parentTableGroup.getNavigablePath().getParent()
|
||||||
);
|
);
|
||||||
|
@ -1420,14 +1420,14 @@ public class ToOneAttributeMapping
|
||||||
NavigablePath path = np.getParent();
|
NavigablePath path = np.getParent();
|
||||||
// Fast path
|
// Fast path
|
||||||
if ( navigablePath.equals( path ) ) {
|
if ( navigablePath.equals( path ) ) {
|
||||||
return targetKeyPropertyNames.contains( np.getUnaliasedLocalName() )
|
return targetKeyPropertyNames.contains( np.getLocalName() )
|
||||||
&& identifyingColumnsTableExpression.equals( tableExpression );
|
&& identifyingColumnsTableExpression.equals( tableExpression );
|
||||||
}
|
}
|
||||||
final StringBuilder sb = new StringBuilder( np.getFullPath().length() );
|
final StringBuilder sb = new StringBuilder( np.getFullPath().length() );
|
||||||
sb.append( np.getUnaliasedLocalName() );
|
sb.append( np.getLocalName() );
|
||||||
while ( path != null && !navigablePath.equals( path ) ) {
|
while ( path != null && !navigablePath.equals( path ) ) {
|
||||||
sb.insert( 0, '.' );
|
sb.insert( 0, '.' );
|
||||||
sb.insert( 0, path.getUnaliasedLocalName() );
|
sb.insert( 0, path.getLocalName() );
|
||||||
path = path.getParent();
|
path = path.getParent();
|
||||||
}
|
}
|
||||||
return navigablePath.equals( path )
|
return navigablePath.equals( path )
|
||||||
|
@ -1542,14 +1542,14 @@ public class ToOneAttributeMapping
|
||||||
NavigablePath path = np.getParent();
|
NavigablePath path = np.getParent();
|
||||||
// Fast path
|
// Fast path
|
||||||
if ( navigablePath.equals( path ) ) {
|
if ( navigablePath.equals( path ) ) {
|
||||||
return targetKeyPropertyNames.contains( np.getUnaliasedLocalName() )
|
return targetKeyPropertyNames.contains( np.getLocalName() )
|
||||||
&& identifyingColumnsTableExpression.equals( tableExpression );
|
&& identifyingColumnsTableExpression.equals( tableExpression );
|
||||||
}
|
}
|
||||||
final StringBuilder sb = new StringBuilder( np.getFullPath().length() );
|
final StringBuilder sb = new StringBuilder( np.getFullPath().length() );
|
||||||
sb.append( np.getUnaliasedLocalName() );
|
sb.append( np.getLocalName() );
|
||||||
while ( path != null && !navigablePath.equals( path ) ) {
|
while ( path != null && !navigablePath.equals( path ) ) {
|
||||||
sb.insert( 0, '.' );
|
sb.insert( 0, '.' );
|
||||||
sb.insert( 0, path.getUnaliasedLocalName() );
|
sb.insert( 0, path.getLocalName() );
|
||||||
path = path.getParent();
|
path = path.getParent();
|
||||||
}
|
}
|
||||||
return navigablePath.equals( path )
|
return navigablePath.equals( path )
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class FunctionExpression implements OrderingExpression, FunctionRendering
|
||||||
final OrderingExpression orderingExpression = arguments.get( i );
|
final OrderingExpression orderingExpression = arguments.get( i );
|
||||||
final String subModelPartName;
|
final String subModelPartName;
|
||||||
if ( orderingExpression instanceof DomainPath ) {
|
if ( orderingExpression instanceof DomainPath ) {
|
||||||
final String partName = ( (DomainPath) orderingExpression ).getNavigablePath().getUnaliasedLocalName();
|
final String partName = ( (DomainPath) orderingExpression ).getNavigablePath().getLocalName();
|
||||||
if ( CollectionPart.Nature.ELEMENT.getName().equals( partName ) ) {
|
if ( CollectionPart.Nature.ELEMENT.getName().equals( partName ) ) {
|
||||||
subModelPartName = AbstractDomainPath.ELEMENT_TOKEN;
|
subModelPartName = AbstractDomainPath.ELEMENT_TOKEN;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4013,7 +4013,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
SqmPath<?> lhs = pluralAttributePath.getLhs();
|
SqmPath<?> lhs = pluralAttributePath.getLhs();
|
||||||
final List<String> implicitJoinPaths = new ArrayList<>();
|
final List<String> implicitJoinPaths = new ArrayList<>();
|
||||||
while ( !( lhs instanceof AbstractSqmFrom<?, ?> ) ) {
|
while ( !( lhs instanceof AbstractSqmFrom<?, ?> ) ) {
|
||||||
implicitJoinPaths.add( lhs.getNavigablePath().getUnaliasedLocalName() );
|
implicitJoinPaths.add( lhs.getNavigablePath().getLocalName() );
|
||||||
lhs = lhs.getLhs();
|
lhs = lhs.getLhs();
|
||||||
}
|
}
|
||||||
final AbstractSqmFrom<?, ?> correlationBase = (AbstractSqmFrom<?, ?>) lhs;
|
final AbstractSqmFrom<?, ?> correlationBase = (AbstractSqmFrom<?, ?>) lhs;
|
||||||
|
@ -4022,7 +4022,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
for ( int i = implicitJoinPaths.size() - 1; i >= 0; i-- ) {
|
for ( int i = implicitJoinPaths.size() - 1; i >= 0; i-- ) {
|
||||||
joinBase = joinBase.join( implicitJoinPaths.get( i ) );
|
joinBase = joinBase.join( implicitJoinPaths.get( i ) );
|
||||||
}
|
}
|
||||||
final SqmAttributeJoin<?, ?> collectionJoin = joinBase.join( pluralAttributePath.getNavigablePath().getUnaliasedLocalName() );
|
final SqmAttributeJoin<?, ?> collectionJoin = joinBase.join( pluralAttributePath.getNavigablePath().getLocalName() );
|
||||||
fromClause.addRoot( correlation.getCorrelatedRoot() );
|
fromClause.addRoot( correlation.getCorrelatedRoot() );
|
||||||
if ( collectionReferenceCtx == null ) {
|
if ( collectionReferenceCtx == null ) {
|
||||||
final SqmLiteral<Integer> literal = new SqmLiteral<>(
|
final SqmLiteral<Integer> literal = new SqmLiteral<>(
|
||||||
|
|
|
@ -240,7 +240,7 @@ public class SqmPathRegistryImpl implements SqmPathRegistry {
|
||||||
return (X) existing;
|
return (X) existing;
|
||||||
}
|
}
|
||||||
|
|
||||||
final SqmFrom<?, ?> sqmFrom = resolveFrom( path.getLhs() ).join( path.getNavigablePath().getUnaliasedLocalName() );
|
final SqmFrom<?, ?> sqmFrom = resolveFrom( path.getLhs() ).join( path.getNavigablePath().getLocalName() );
|
||||||
register( sqmFrom );
|
register( sqmFrom );
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return (X) sqmFrom;
|
return (X) sqmFrom;
|
||||||
|
|
|
@ -171,6 +171,6 @@ public class ImplicitFetchBuilderEmbeddable implements ImplicitFetchBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitFetchBuilders(BiConsumer<String, FetchBuilder> consumer) {
|
public void visitFetchBuilders(BiConsumer<String, FetchBuilder> consumer) {
|
||||||
fetchBuilders.forEach( (k, v) -> consumer.accept( k.getUnaliasedLocalName(), v ) );
|
fetchBuilders.forEach( (k, v) -> consumer.accept( k.getLocalName(), v ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ public class ImplicitFetchBuilderEntity implements ImplicitFetchBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitFetchBuilders(BiConsumer<String, FetchBuilder> consumer) {
|
public void visitFetchBuilders(BiConsumer<String, FetchBuilder> consumer) {
|
||||||
fetchBuilders.forEach( (k, v) -> consumer.accept( k.getUnaliasedLocalName(), v ) );
|
fetchBuilders.forEach( (k, v) -> consumer.accept( k.getLocalName(), v ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2983,7 +2983,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
prepareReusablePath( path, () -> null );
|
prepareReusablePath( path, () -> null );
|
||||||
|
|
||||||
final NavigablePath navigablePath;
|
final NavigablePath navigablePath;
|
||||||
if ( CollectionPart.Nature.fromNameExact( path.getNavigablePath().getUnaliasedLocalName() ) != null ) {
|
if ( CollectionPart.Nature.fromNameExact( path.getNavigablePath().getLocalName() ) != null ) {
|
||||||
navigablePath = path.getLhs().getLhs().getNavigablePath();
|
navigablePath = path.getLhs().getLhs().getNavigablePath();
|
||||||
}
|
}
|
||||||
else if ( path instanceof SqmTreatedRoot<?, ?> ) {
|
else if ( path instanceof SqmTreatedRoot<?, ?> ) {
|
||||||
|
@ -3648,7 +3648,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
assert parentTableGroup != null;
|
assert parentTableGroup != null;
|
||||||
|
|
||||||
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) parentTableGroup.getModelPart().findSubPart(
|
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) parentTableGroup.getModelPart().findSubPart(
|
||||||
pluralPath.getNavigablePath().getUnaliasedLocalName(),
|
pluralPath.getNavigablePath().getLocalName(),
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
assert pluralAttributeMapping != null;
|
assert pluralAttributeMapping != null;
|
||||||
|
@ -5344,7 +5344,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
path.getLhs().getNavigablePath()
|
path.getLhs().getNavigablePath()
|
||||||
);
|
);
|
||||||
final NavigablePath navigablePath = parentTableGroup.getNavigablePath().append(
|
final NavigablePath navigablePath = parentTableGroup.getNavigablePath().append(
|
||||||
path.getNavigablePath().getUnaliasedLocalName(),
|
path.getNavigablePath().getLocalName(),
|
||||||
Long.toString( System.nanoTime() )
|
Long.toString( System.nanoTime() )
|
||||||
);
|
);
|
||||||
final TableGroup tableGroup = new SyntheticVirtualTableGroup(
|
final TableGroup tableGroup = new SyntheticVirtualTableGroup(
|
||||||
|
|
|
@ -103,7 +103,7 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
|
||||||
reusablePaths = new HashMap<>();
|
reusablePaths = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
final String relativeName = path.getNavigablePath().getUnaliasedLocalName();
|
final String relativeName = path.getNavigablePath().getLocalName();
|
||||||
|
|
||||||
final SqmPath<?> previous = reusablePaths.put( relativeName, path );
|
final SqmPath<?> previous = reusablePaths.put( relativeName, path );
|
||||||
if ( previous != null && previous != path ) {
|
if ( previous != null && previous != path ) {
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class SqmPluralValuedSimplePath<E> extends AbstractSqmSimplePath<E> {
|
||||||
final SqmPathRegistry pathRegistry = creationState.getCurrentProcessingState().getPathRegistry();
|
final SqmPathRegistry pathRegistry = creationState.getCurrentProcessingState().getPathRegistry();
|
||||||
final String alias = selector.toHqlString();
|
final String alias = selector.toHqlString();
|
||||||
final NavigablePath navigablePath = getNavigablePath().getParent().append(
|
final NavigablePath navigablePath = getNavigablePath().getParent().append(
|
||||||
getNavigablePath().getUnaliasedLocalName(),
|
getNavigablePath().getLocalName(),
|
||||||
alias
|
alias
|
||||||
).append( CollectionPart.Nature.ELEMENT.getName() );
|
).append( CollectionPart.Nature.ELEMENT.getName() );
|
||||||
final SqmFrom<?, ?> indexedPath = pathRegistry.findFromByPath( navigablePath );
|
final SqmFrom<?, ?> indexedPath = pathRegistry.findFromByPath( navigablePath );
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class SqmAliasedNodeRef extends AbstractSqmExpression<Integer> {
|
||||||
sb.append( position );
|
sb.append( position );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sb.append( navigablePath.getUnaliasedLocalName() );
|
sb.append( navigablePath.getLocalName() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,23 +23,28 @@ public class NavigablePath implements DotIdentifierSequence, Serializable {
|
||||||
public static final String IDENTIFIER_MAPPER_PROPERTY = "_identifierMapper";
|
public static final String IDENTIFIER_MAPPER_PROPERTY = "_identifierMapper";
|
||||||
|
|
||||||
private final NavigablePath parent;
|
private final NavigablePath parent;
|
||||||
private final String fullPath;
|
private final String localName;
|
||||||
private final String unaliasedLocalName;
|
private final String alias;
|
||||||
|
|
||||||
private final String identifierForTableGroup;
|
private final String identifierForTableGroup;
|
||||||
|
|
||||||
|
private final String fullPath;
|
||||||
|
|
||||||
public NavigablePath(NavigablePath parent, String navigableName) {
|
public NavigablePath(NavigablePath parent, String navigableName) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
this.alias = null;
|
||||||
|
|
||||||
// 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( navigableName ) ) {
|
||||||
this.fullPath = parent != null ? parent.getFullPath() : "";
|
this.localName = "";
|
||||||
this.unaliasedLocalName = "";
|
|
||||||
this.identifierForTableGroup = parent != null ? parent.getIdentifierForTableGroup() : "";
|
this.identifierForTableGroup = parent != null ? parent.getIdentifierForTableGroup() : "";
|
||||||
|
|
||||||
|
this.fullPath = parent != null ? parent.getFullPath() : "";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.unaliasedLocalName = navigableName;
|
this.localName = navigableName;
|
||||||
if ( parent != null ) {
|
if ( parent != null ) {
|
||||||
final String parentFullPath = parent.getFullPath();
|
final String parentFullPath = parent.getFullPath();
|
||||||
this.fullPath = StringHelper.isEmpty( parentFullPath )
|
this.fullPath = StringHelper.isEmpty( parentFullPath )
|
||||||
|
@ -51,7 +56,7 @@ public class NavigablePath implements DotIdentifierSequence, Serializable {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.fullPath = navigableName;
|
this.fullPath = navigableName;
|
||||||
identifierForTableGroup = navigableName;
|
this.identifierForTableGroup = navigableName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,28 +67,32 @@ 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.localName = rootName;
|
||||||
|
this.identifierForTableGroup = rootName;
|
||||||
|
|
||||||
this.fullPath = alias == null ? rootName : rootName + "(" + alias + ")";
|
this.fullPath = alias == null ? rootName : rootName + "(" + alias + ")";
|
||||||
this.unaliasedLocalName = StringHelper.unqualify( rootName );
|
|
||||||
identifierForTableGroup = rootName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public NavigablePath(NavigablePath parent, String property, String alias) {
|
public NavigablePath(NavigablePath parent, String property, String alias) {
|
||||||
String navigableName = alias == null
|
alias = StringHelper.nullIfEmpty( alias );
|
||||||
|
final String navigableName = alias == null
|
||||||
? property
|
? property
|
||||||
: property + '(' + alias + ')';
|
: property + '(' + alias + ')';
|
||||||
|
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
this.alias = alias;
|
||||||
|
|
||||||
// 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( navigableName ) ) {
|
||||||
this.fullPath = parent != null ? parent.getFullPath() : "";
|
this.fullPath = parent != null ? parent.getFullPath() : "";
|
||||||
this.unaliasedLocalName = "";
|
this.localName = "";
|
||||||
identifierForTableGroup = parent != null ? parent.getFullPath() : "";
|
identifierForTableGroup = parent != null ? parent.getFullPath() : "";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.unaliasedLocalName = property;
|
this.localName = property;
|
||||||
if ( parent != null ) {
|
if ( parent != null ) {
|
||||||
final String parentFullPath = parent.getFullPath();
|
final String parentFullPath = parent.getFullPath();
|
||||||
this.fullPath = StringHelper.isEmpty( parentFullPath )
|
this.fullPath = StringHelper.isEmpty( parentFullPath )
|
||||||
|
@ -107,11 +116,12 @@ public class NavigablePath implements DotIdentifierSequence, Serializable {
|
||||||
public NavigablePath(
|
public NavigablePath(
|
||||||
NavigablePath parent,
|
NavigablePath parent,
|
||||||
String fullPath,
|
String fullPath,
|
||||||
String unaliasedLocalName,
|
String localName,
|
||||||
String identifierForTableGroup) {
|
String identifierForTableGroup) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
this.alias = null;
|
||||||
this.fullPath = fullPath;
|
this.fullPath = fullPath;
|
||||||
this.unaliasedLocalName = unaliasedLocalName;
|
this.localName = localName;
|
||||||
this.identifierForTableGroup = identifierForTableGroup;
|
this.identifierForTableGroup = identifierForTableGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,24 +150,29 @@ public class NavigablePath implements DotIdentifierSequence, Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLocalName() {
|
public String getLocalName() {
|
||||||
return parent == null ? fullPath : StringHelper.unqualify( fullPath );
|
return localName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUnaliasedLocalName() {
|
public String getAlias() {
|
||||||
return unaliasedLocalName;
|
return alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFullPath() {
|
public boolean isAliased() {
|
||||||
return fullPath;
|
return alias != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIdentifierForTableGroup() {
|
public String getIdentifierForTableGroup() {
|
||||||
|
// todo (6.0) : is this `if` really needed? seems this is already handled in constructors
|
||||||
if ( parent == null ) {
|
if ( parent == null ) {
|
||||||
return fullPath;
|
return fullPath;
|
||||||
}
|
}
|
||||||
return identifierForTableGroup;
|
return identifierForTableGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getFullPath() {
|
||||||
|
return fullPath;
|
||||||
|
}
|
||||||
|
|
||||||
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() ) ) {
|
||||||
|
|
|
@ -41,11 +41,6 @@ public class TreatedNavigablePath extends NavigablePath {
|
||||||
return new TreatedNavigablePath( getRealParent(), entityName, alias );
|
return new TreatedNavigablePath( getRealParent(), entityName, alias );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLocalName() {
|
|
||||||
return getUnaliasedLocalName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return getFullPath().hashCode();
|
return getFullPath().hashCode();
|
||||||
|
|
|
@ -108,9 +108,9 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
||||||
);
|
);
|
||||||
|
|
||||||
// We never want to create empty composites for the FK target or PK, otherwise collections would break
|
// We never want to create empty composites for the FK target or PK, otherwise collections would break
|
||||||
createEmptyCompositesEnabled = !ForeignKeyDescriptor.PART_NAME.equals( navigablePath.getUnaliasedLocalName() )
|
createEmptyCompositesEnabled = !ForeignKeyDescriptor.PART_NAME.equals( navigablePath.getLocalName() )
|
||||||
&& !ForeignKeyDescriptor.TARGET_PART_NAME.equals( navigablePath.getUnaliasedLocalName() )
|
&& !ForeignKeyDescriptor.TARGET_PART_NAME.equals( navigablePath.getLocalName() )
|
||||||
&& !EntityIdentifierMapping.ROLE_LOCAL_NAME.equals( navigablePath.getUnaliasedLocalName() )
|
&& !EntityIdentifierMapping.ROLE_LOCAL_NAME.equals( navigablePath.getLocalName() )
|
||||||
&& embeddableTypeDescriptor.isCreateEmptyCompositesEnabled();
|
&& embeddableTypeDescriptor.isCreateEmptyCompositesEnabled();
|
||||||
|
|
||||||
sessionFactory = creationState.getSqlAstCreationContext().getSessionFactory();
|
sessionFactory = creationState.getSqlAstCreationContext().getSessionFactory();
|
||||||
|
@ -232,8 +232,8 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
||||||
// so we can't use the fetch parent access in that case.
|
// so we can't use the fetch parent access in that case.
|
||||||
if ( fetchParentAccess != null && embedded instanceof VirtualModelPart
|
if ( fetchParentAccess != null && embedded instanceof VirtualModelPart
|
||||||
&& !EntityIdentifierMapping.ROLE_LOCAL_NAME.equals( embedded.getFetchableName() )
|
&& !EntityIdentifierMapping.ROLE_LOCAL_NAME.equals( embedded.getFetchableName() )
|
||||||
&& !ForeignKeyDescriptor.PART_NAME.equals( navigablePath.getUnaliasedLocalName() )
|
&& !ForeignKeyDescriptor.PART_NAME.equals( navigablePath.getLocalName() )
|
||||||
&& !ForeignKeyDescriptor.TARGET_PART_NAME.equals( navigablePath.getUnaliasedLocalName() ) ) {
|
&& !ForeignKeyDescriptor.TARGET_PART_NAME.equals( navigablePath.getLocalName() ) ) {
|
||||||
fetchParentAccess.resolveInstance( processingState );
|
fetchParentAccess.resolveInstance( processingState );
|
||||||
compositeInstance = fetchParentAccess.getInitializedInstance();
|
compositeInstance = fetchParentAccess.getInitializedInstance();
|
||||||
}
|
}
|
||||||
|
@ -255,8 +255,8 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
||||||
|
|
||||||
private void extractRowState(RowProcessingState processingState) {
|
private void extractRowState(RowProcessingState processingState) {
|
||||||
stateAllNull = true;
|
stateAllNull = true;
|
||||||
final boolean isKey = ForeignKeyDescriptor.PART_NAME.equals( navigablePath.getUnaliasedLocalName() )
|
final boolean isKey = ForeignKeyDescriptor.PART_NAME.equals( navigablePath.getLocalName() )
|
||||||
|| ForeignKeyDescriptor.TARGET_PART_NAME.equals( navigablePath.getUnaliasedLocalName() )
|
|| ForeignKeyDescriptor.TARGET_PART_NAME.equals( navigablePath.getLocalName() )
|
||||||
|| EntityIdentifierMapping.ROLE_LOCAL_NAME.equals( embedded.getFetchableName() );
|
|| EntityIdentifierMapping.ROLE_LOCAL_NAME.equals( embedded.getFetchableName() );
|
||||||
for ( int i = 0; i < assemblers.size(); i++ ) {
|
for ( int i = 0; i < assemblers.size(); i++ ) {
|
||||||
final DomainResultAssembler<?> assembler = assemblers.get( i );
|
final DomainResultAssembler<?> assembler = assemblers.get( i );
|
||||||
|
|
|
@ -112,7 +112,7 @@ public class EmbeddableFetchImpl extends AbstractFetchParent implements Embeddab
|
||||||
for ( TableGroupJoin tableGroupJoin : tableGroup.getTableGroupJoins() ) {
|
for ( TableGroupJoin tableGroupJoin : tableGroup.getTableGroupJoins() ) {
|
||||||
final NavigablePath navigablePath = tableGroupJoin.getNavigablePath();
|
final NavigablePath navigablePath = tableGroupJoin.getNavigablePath();
|
||||||
if ( tableGroupJoin.getJoinedGroup().isFetched()
|
if ( tableGroupJoin.getJoinedGroup().isFetched()
|
||||||
&& fetchable.getFetchableName().equals( navigablePath.getUnaliasedLocalName() )
|
&& fetchable.getFetchableName().equals( navigablePath.getLocalName() )
|
||||||
&& tableGroupJoin.getJoinedGroup().getModelPart() == fetchable ) {
|
&& tableGroupJoin.getJoinedGroup().getModelPart() == fetchable ) {
|
||||||
return navigablePath;
|
return navigablePath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,12 +56,11 @@ public class EntityResultImpl extends AbstractEntityResultGraphNode implements E
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NavigablePath resolveNavigablePath(Fetchable fetchable) {
|
public NavigablePath resolveNavigablePath(Fetchable fetchable) {
|
||||||
if ( fetchable instanceof TableGroupProducer &&
|
if ( fetchable instanceof TableGroupProducer && getNavigablePath().isAliased() ) {
|
||||||
!getNavigablePath().getUnaliasedLocalName().equals( getNavigablePath().getLocalName() ) ) {
|
|
||||||
for ( TableGroupJoin tableGroupJoin : tableGroup.getTableGroupJoins() ) {
|
for ( TableGroupJoin tableGroupJoin : tableGroup.getTableGroupJoins() ) {
|
||||||
final NavigablePath navigablePath = tableGroupJoin.getNavigablePath();
|
final NavigablePath navigablePath = tableGroupJoin.getNavigablePath();
|
||||||
if ( tableGroupJoin.getJoinedGroup().isFetched()
|
if ( tableGroupJoin.getJoinedGroup().isFetched()
|
||||||
&& fetchable.getFetchableName().equals( navigablePath.getUnaliasedLocalName() )
|
&& fetchable.getFetchableName().equals( navigablePath.getLocalName() )
|
||||||
&& tableGroupJoin.getJoinedGroup().getModelPart() == fetchable ) {
|
&& tableGroupJoin.getJoinedGroup().getModelPart() == fetchable ) {
|
||||||
return navigablePath;
|
return navigablePath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,8 +88,8 @@ public class EntitySelectFetchInitializer extends AbstractFetchParentAccess impl
|
||||||
NavigablePath np = navigablePath.getParent();
|
NavigablePath np = navigablePath.getParent();
|
||||||
while ( np != null ) {
|
while ( np != null ) {
|
||||||
if ( np instanceof EntityIdentifierNavigablePath
|
if ( np instanceof EntityIdentifierNavigablePath
|
||||||
|| ForeignKeyDescriptor.PART_NAME.equals( np.getUnaliasedLocalName() )
|
|| ForeignKeyDescriptor.PART_NAME.equals( np.getLocalName() )
|
||||||
|| ForeignKeyDescriptor.TARGET_PART_NAME.equals( np.getUnaliasedLocalName() )) {
|
|| ForeignKeyDescriptor.TARGET_PART_NAME.equals( np.getLocalName() )) {
|
||||||
initializeInstance( rowProcessingState );
|
initializeInstance( rowProcessingState );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.spi.path;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||||
|
import org.hibernate.spi.EntityIdentifierNavigablePath;
|
||||||
|
import org.hibernate.spi.NavigablePath;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class NavigablePathTests {
|
||||||
|
@Test
|
||||||
|
public void testRoots() {
|
||||||
|
final NavigablePath root = new NavigablePath( "org.hibernate.Root", "r" );
|
||||||
|
assertThat( root.equals( root ) ).isTrue();
|
||||||
|
assertThat( root.getFullPath() ).isEqualTo( "org.hibernate.Root(r)" );
|
||||||
|
assertThat( root.getLocalName() ).isEqualTo( "org.hibernate.Root" );
|
||||||
|
assertThat( root.isAliased() ).isTrue();
|
||||||
|
assertThat( root.getAlias() ).isEqualTo( "r" );
|
||||||
|
|
||||||
|
final NavigablePath root2 = new NavigablePath( "org.hibernate.Root", "r" );
|
||||||
|
assertThat( root.equals( root2 ) ).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSubPaths() {
|
||||||
|
final NavigablePath root = new NavigablePath( "org.hibernate.Root", "r" );
|
||||||
|
|
||||||
|
final NavigablePath name1 = root.append( "name" );
|
||||||
|
final NavigablePath name2 = root.append( "name" );
|
||||||
|
|
||||||
|
assertThat( name1.equals( name2 ) ).isTrue();
|
||||||
|
|
||||||
|
final NavigablePath id = root.append( "id" );
|
||||||
|
|
||||||
|
assertThat( name1.equals( root ) ).isFalse();
|
||||||
|
assertThat( id.equals( root ) ).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParallelSubPaths() {
|
||||||
|
final NavigablePath root1 = new NavigablePath( "org.hibernate.Root", "r" );
|
||||||
|
final NavigablePath root2 = new NavigablePath( "org.hibernate.Root", "r" );
|
||||||
|
|
||||||
|
final NavigablePath name1 = root1.append( "name" );
|
||||||
|
final NavigablePath name2 = root2.append( "name" );
|
||||||
|
|
||||||
|
assertThat( name1.equals( name2 ) ).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNestedPaths() {
|
||||||
|
final NavigablePath root = new NavigablePath( "org.hibernate.Root", "r" );
|
||||||
|
|
||||||
|
final NavigablePath comp1 = root.append( "comp" );
|
||||||
|
final NavigablePath comp2 = root.append( "comp" );
|
||||||
|
|
||||||
|
final NavigablePath comp1Name = comp1.append( "name" );
|
||||||
|
final NavigablePath comp2Name = comp2.append( "name" );
|
||||||
|
|
||||||
|
assertThat( comp1Name.equals( comp2Name ) ).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDivergentNestedPaths() {
|
||||||
|
final NavigablePath root = new NavigablePath( "org.hibernate.Root", "r" );
|
||||||
|
|
||||||
|
final NavigablePath comp = root.append( "comp" );
|
||||||
|
final NavigablePath other = root.append( "other" );
|
||||||
|
|
||||||
|
final NavigablePath compName = comp.append( "name" );
|
||||||
|
final NavigablePath otherName = other.append( "name" );
|
||||||
|
|
||||||
|
assertThat( compName.equals( otherName ) ).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStringification() {
|
||||||
|
final String rootStr = "org.hibernate.Root";
|
||||||
|
final String aliasedRootStr = "org.hibernate.Root(r)";
|
||||||
|
final String nameStr = "name";
|
||||||
|
final String namePathStr = aliasedRootStr + "." + nameStr;
|
||||||
|
|
||||||
|
final NavigablePath root = new NavigablePath( rootStr, "r" );
|
||||||
|
|
||||||
|
final NavigablePath name = root.append( "name" );
|
||||||
|
assertThat( name.getLocalName() ).isEqualTo( nameStr );
|
||||||
|
assertThat( name.getFullPath() ).isEqualTo( namePathStr );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIdentifierPaths() {
|
||||||
|
final String rootStr = "org.hibernate.Root";
|
||||||
|
final String aliasedRootStr = "org.hibernate.Root(r)";
|
||||||
|
|
||||||
|
final String pkStr = "pk";
|
||||||
|
final String pkFullPathStr = aliasedRootStr + "." + EntityIdentifierMapping.ROLE_LOCAL_NAME;
|
||||||
|
|
||||||
|
final NavigablePath root = new NavigablePath( rootStr, "r" );
|
||||||
|
|
||||||
|
final NavigablePath idPath = new EntityIdentifierNavigablePath( root, pkStr );
|
||||||
|
assertThat( idPath.getLocalName() ).isEqualTo( EntityIdentifierMapping.ROLE_LOCAL_NAME );
|
||||||
|
assertThat( idPath.getFullPath() ).isEqualTo( pkFullPathStr );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue