From 8470d6db5bb104cb1badc46a2852e06b80369c45 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Tue, 22 Mar 2022 18:21:29 -0500 Subject: [PATCH] HHH-15132 - Improvements for NavigablePath - additional refactoring of uses of `NavigablePath#getFullPath` --- .../internal/EntityCollectionPart.java | 42 ++++++------- .../internal/ToOneAttributeMapping.java | 54 ++++++++--------- .../java/org/hibernate/spi/NavigablePath.java | 60 +++++++++++++++++++ 3 files changed, 105 insertions(+), 51 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityCollectionPart.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityCollectionPart.java index 6b8786fc67..b2a116cf11 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityCollectionPart.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EntityCollectionPart.java @@ -18,6 +18,7 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.FetchStyle; import org.hibernate.engine.FetchTiming; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.internal.util.StringHelper; import org.hibernate.mapping.Collection; import org.hibernate.mapping.IndexedCollection; import org.hibernate.mapping.Map; @@ -85,7 +86,6 @@ public class EntityCollectionPart private final Nature nature; private final EntityMappingType entityMappingType; private final Set targetKeyPropertyNames; - private final NotFoundAction notFoundAction; private ModelPart fkTargetModelPart; private ForeignKeyDescriptor fkDescriptor; @@ -94,30 +94,28 @@ public class EntityCollectionPart CollectionPersister collectionDescriptor, Nature nature, Value bootModelValue, - NotFoundAction notFoundAction, + @SuppressWarnings("unused") NotFoundAction notFoundAction, EntityMappingType entityMappingType, MappingModelCreationProcess creationProcess) { - this.notFoundAction = notFoundAction; this.navigableRole = collectionDescriptor.getNavigableRole().appendContainer( nature.getName() ); this.collectionDescriptor = collectionDescriptor; this.nature = nature; this.entityMappingType = entityMappingType; + final PersistentClass entityBinding = creationProcess.getCreationContext() + .getMetadata() + .getEntityBinding( entityMappingType.getEntityName() ); final String referencedPropertyName; - final PersistentClass entityBinding; + if ( bootModelValue instanceof OneToMany ) { final String mappedByProperty = collectionDescriptor.getMappedByProperty(); - referencedPropertyName = mappedByProperty == null || mappedByProperty.isEmpty() + referencedPropertyName = StringHelper.isEmpty( mappedByProperty ) ? null : mappedByProperty; - entityBinding = ( (OneToMany) bootModelValue ).getBuildingContext().getMetadataCollector() - .getEntityBinding( entityMappingType.getEntityName() ); } else { final ToOne toOne = (ToOne) bootModelValue; referencedPropertyName = toOne.getReferencedPropertyName(); - entityBinding = toOne.getBuildingContext().getMetadataCollector() - .getEntityBinding( entityMappingType.getEntityName() ); } if ( referencedPropertyName == null ) { @@ -664,22 +662,20 @@ public class EntityCollectionPart creationContext ), (np, tableExpression) -> { - NavigablePath path = np.getParent(); - // Fast path - if ( navigablePath.equals( path ) ) { - return targetKeyPropertyNames.contains( np.getLocalName() ) - && fkDescriptor.getKeyTable().equals( tableExpression ); + if ( ! fkDescriptor.getKeyTable().equals( tableExpression ) ) { + return false; } - final StringBuilder sb = new StringBuilder( np.getFullPath().length() ); - sb.append( np.getLocalName() ); - while ( path != null && !navigablePath.equals( path ) ) { - sb.insert( 0, '.' ); - sb.insert( 0, path.getLocalName() ); - path = path.getParent(); + + if ( navigablePath.equals( np.getParent() ) ) { + return targetKeyPropertyNames.contains( np.getLocalName() ); } - return navigablePath.equals( path ) - && targetKeyPropertyNames.contains( sb.toString() ) - && fkDescriptor.getKeyTable().equals( tableExpression ); + + final String relativePath = np.relativize( navigablePath ); + if ( relativePath == null ) { + return false; + } + + return targetKeyPropertyNames.contains( relativePath ); }, this, explicitSourceAlias, 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 5dd58d098c..4e10983beb 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 @@ -1417,22 +1417,21 @@ public class ToOneAttributeMapping if ( !canUseParentTableGroup ) { return false; } - NavigablePath path = np.getParent(); - // Fast path - if ( navigablePath.equals( path ) ) { - return targetKeyPropertyNames.contains( np.getLocalName() ) - && identifyingColumnsTableExpression.equals( tableExpression ); + + if ( !identifyingColumnsTableExpression.equals( tableExpression ) ) { + return false; } - final StringBuilder sb = new StringBuilder( np.getFullPath().length() ); - sb.append( np.getLocalName() ); - while ( path != null && !navigablePath.equals( path ) ) { - sb.insert( 0, '.' ); - sb.insert( 0, path.getLocalName() ); - path = path.getParent(); + + if ( navigablePath.equals( np.getParent() ) ) { + return targetKeyPropertyNames.contains( np.getLocalName() ); } - return navigablePath.equals( path ) - && targetKeyPropertyNames.contains( sb.toString() ) - && identifyingColumnsTableExpression.equals( tableExpression ); + + final String relativePath = np.relativize( navigablePath ); + if ( relativePath == null ) { + return false; + } + + return targetKeyPropertyNames.contains( relativePath ); } ), null @@ -1539,22 +1538,21 @@ public class ToOneAttributeMapping if ( !canUseParentTableGroup || tableGroupProducer != ToOneAttributeMapping.this ) { return false; } - NavigablePath path = np.getParent(); - // Fast path - if ( navigablePath.equals( path ) ) { - return targetKeyPropertyNames.contains( np.getLocalName() ) - && identifyingColumnsTableExpression.equals( tableExpression ); + + if ( !identifyingColumnsTableExpression.equals( tableExpression ) ) { + return false; } - final StringBuilder sb = new StringBuilder( np.getFullPath().length() ); - sb.append( np.getLocalName() ); - while ( path != null && !navigablePath.equals( path ) ) { - sb.insert( 0, '.' ); - sb.insert( 0, path.getLocalName() ); - path = path.getParent(); + + if ( navigablePath.equals( np.getParent() ) ) { + return targetKeyPropertyNames.contains( np.getLocalName() ); } - return navigablePath.equals( path ) - && targetKeyPropertyNames.contains( sb.toString() ) - && identifyingColumnsTableExpression.equals( tableExpression ); + + final String relativePath = np.relativize( navigablePath ); + if ( relativePath == null ) { + return false; + } + + return targetKeyPropertyNames.contains( relativePath ); }, tableGroupProducer, explicitSourceAlias, 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 44d33a3088..64daed7c54 100644 --- a/hibernate-core/src/main/java/org/hibernate/spi/NavigablePath.java +++ b/hibernate-core/src/main/java/org/hibernate/spi/NavigablePath.java @@ -191,6 +191,66 @@ public class NavigablePath implements DotIdentifierSequence, Serializable { return false; } + /** + * Ignores aliases in the resulting String + */ + public String relativize(NavigablePath base) { + // e.g. + // - base = Root.sub + // - this = Root.sub.stuff + // - result = stuff + // e.g. 2 + // - base = Root.sub + // - this = Root.sub.leaf.terminal + // - result = leaf.terminal + + final RelativePathCollector pathCollector = new RelativePathCollector(); + relativize( base, pathCollector ); + return pathCollector.resolve(); + } + + protected static class RelativePathCollector { + private boolean matchedBase; + private StringBuilder buffer; + + public void collectPath(String path) { + if ( !matchedBase ) { + return; + } + + if ( buffer == null ) { + buffer = new StringBuilder(); + } + else { + buffer.append( '.' ); + } + + buffer.append( path ); + } + + public String resolve() { + if ( buffer == null ) { + return null; + } + return buffer.toString(); + } + } + + protected void relativize(NavigablePath base, RelativePathCollector collector) { + if ( this == base ) { + collector.matchedBase = true; + return; + } + + if ( ! collector.matchedBase ) { + if ( parent != null ) { + parent.relativize( base, collector ); + } + } + + collector.collectPath( getLocalName() ); + } + @Override public String getFullPath() { return fullPathCalculator.calculateFullPath( parent, localName, alias );