From f4d044f63a54a86f2611fe3eb8aac972ce3662ea Mon Sep 17 00:00:00 2001 From: Marco Pelagatti Date: Mon, 27 May 2024 18:18:55 +0200 Subject: [PATCH] HHH-18170 Subquery randomly generating wrong SQL due to duplicate alias --- .../org/hibernate/query/sqm/spi/SqmCreationHelper.java | 10 +++++++++- .../sqm/sql/internal/EmbeddableValuedExpression.java | 3 ++- .../query/sqm/tree/AbstractSqmDmlStatement.java | 7 ++++--- .../query/sqm/tree/select/AbstractSqmSelectQuery.java | 7 ++++--- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/spi/SqmCreationHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/spi/SqmCreationHelper.java index 09f187f73d..1c43c1ae9b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/spi/SqmCreationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/spi/SqmCreationHelper.java @@ -11,6 +11,8 @@ import org.hibernate.metamodel.model.domain.PluralPersistentAttribute; import org.hibernate.spi.NavigablePath; import org.hibernate.query.sqm.tree.domain.SqmPath; +import java.util.concurrent.atomic.AtomicLong; + /** * @author Steve Ebersole */ @@ -27,6 +29,8 @@ public class SqmCreationHelper { */ public static final String IMPLICIT_ALIAS = "{implicit}"; + private static final AtomicLong UNIQUE_ID_COUNTER = new AtomicLong(); + public static NavigablePath buildRootNavigablePath(String base, String alias) { return new NavigablePath( base, determineAlias( alias ) ); } @@ -35,10 +39,14 @@ public class SqmCreationHelper { return lhs.append( base, determineAlias( alias ) ); } + public static String acquireUniqueAlias() { + return Long.toString(UNIQUE_ID_COUNTER.incrementAndGet()); + } + public static String determineAlias(String alias) { // Make sure we always create a unique alias, otherwise we might use a wrong table group for the same join if ( alias == null ) { - return Long.toString( System.nanoTime() ); + return acquireUniqueAlias(); } else if ( alias == IMPLICIT_ALIAS ) { return null; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/EmbeddableValuedExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/EmbeddableValuedExpression.java index d54b8c3deb..d477397522 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/EmbeddableValuedExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/internal/EmbeddableValuedExpression.java @@ -15,6 +15,7 @@ import org.hibernate.metamodel.mapping.EmbeddableMappingType; import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart; import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping; +import org.hibernate.query.sqm.spi.SqmCreationHelper; import org.hibernate.spi.NavigablePath; import org.hibernate.sql.ast.SqlAstWalker; import org.hibernate.sql.ast.spi.SqlAstCreationState; @@ -46,7 +47,7 @@ public class EmbeddableValuedExpression implements Expression, DomainResultPr assert mapping != null; assert sqlExpression != null; assert mapping.getEmbeddableTypeDescriptor().getNumberOfAttributeMappings() == sqlExpression.getExpressions().size(); - this.navigablePath = baseNavigablePath.append( mapping.getPartName(), Long.toString( System.nanoTime() ) ); + this.navigablePath = baseNavigablePath.append( mapping.getPartName(), SqmCreationHelper.acquireUniqueAlias()); this.mapping = mapping; this.sqlExpression = sqlExpression; } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/AbstractSqmDmlStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/AbstractSqmDmlStatement.java index 8cb08bcbb9..23857af453 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/AbstractSqmDmlStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/AbstractSqmDmlStatement.java @@ -16,6 +16,7 @@ import org.hibernate.query.criteria.JpaCteCriteria; import org.hibernate.query.criteria.JpaRoot; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SqmQuerySource; +import org.hibernate.query.sqm.spi.SqmCreationHelper; import org.hibernate.query.sqm.tree.cte.SqmCteContainer; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; import org.hibernate.query.sqm.tree.expression.SqmParameter; @@ -93,21 +94,21 @@ public abstract class AbstractSqmDmlStatement @Override public JpaCteCriteria with(AbstractQuery criteria) { - return withInternal( Long.toString( System.nanoTime() ), criteria ); + return withInternal( SqmCreationHelper.acquireUniqueAlias(), criteria ); } @Override public JpaCteCriteria withRecursiveUnionAll( AbstractQuery baseCriteria, Function, AbstractQuery> recursiveCriteriaProducer) { - return withInternal( Long.toString( System.nanoTime() ), baseCriteria, false, recursiveCriteriaProducer ); + return withInternal( SqmCreationHelper.acquireUniqueAlias(), baseCriteria, false, recursiveCriteriaProducer ); } @Override public JpaCteCriteria withRecursiveUnionDistinct( AbstractQuery baseCriteria, Function, AbstractQuery> recursiveCriteriaProducer) { - return withInternal( Long.toString( System.nanoTime() ), baseCriteria, true, recursiveCriteriaProducer ); + return withInternal( SqmCreationHelper.acquireUniqueAlias(), baseCriteria, true, recursiveCriteriaProducer ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/AbstractSqmSelectQuery.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/AbstractSqmSelectQuery.java index 338dae4ab6..e298efe937 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/AbstractSqmSelectQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/AbstractSqmSelectQuery.java @@ -19,6 +19,7 @@ import org.hibernate.query.criteria.JpaCteCriteria; import org.hibernate.query.criteria.JpaRoot; import org.hibernate.query.criteria.JpaSelection; import org.hibernate.query.sqm.NodeBuilder; +import org.hibernate.query.sqm.spi.SqmCreationHelper; import org.hibernate.query.sqm.tree.AbstractSqmNode; import org.hibernate.query.sqm.tree.SqmCopyContext; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; @@ -114,21 +115,21 @@ public abstract class AbstractSqmSelectQuery @Override public JpaCteCriteria with(AbstractQuery criteria) { - return withInternal( Long.toString( System.nanoTime() ), criteria ); + return withInternal( SqmCreationHelper.acquireUniqueAlias(), criteria ); } @Override public JpaCteCriteria withRecursiveUnionAll( AbstractQuery baseCriteria, Function, AbstractQuery> recursiveCriteriaProducer) { - return withInternal( Long.toString( System.nanoTime() ), baseCriteria, false, recursiveCriteriaProducer ); + return withInternal( SqmCreationHelper.acquireUniqueAlias(), baseCriteria, false, recursiveCriteriaProducer ); } @Override public JpaCteCriteria withRecursiveUnionDistinct( AbstractQuery baseCriteria, Function, AbstractQuery> recursiveCriteriaProducer) { - return withInternal( Long.toString( System.nanoTime() ), baseCriteria, true, recursiveCriteriaProducer ); + return withInternal( SqmCreationHelper.acquireUniqueAlias(), baseCriteria, true, recursiveCriteriaProducer ); } @Override