HHH-18170 Subquery randomly generating wrong SQL due to duplicate alias

This commit is contained in:
Marco Pelagatti 2024-05-27 18:18:55 +02:00 committed by Christian Beikov
parent 1919409ffc
commit 3790c19ccc
4 changed files with 19 additions and 8 deletions

View File

@ -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;

View File

@ -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<T> 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;
}

View File

@ -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.SqmCteStatement;
import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.from.SqmRoot;
@ -84,21 +85,21 @@ public abstract class AbstractSqmDmlStatement<E>
@Override
public <X> JpaCteCriteria<X> with(AbstractQuery<X> criteria) {
return withInternal( Long.toString( System.nanoTime() ), criteria );
return withInternal( SqmCreationHelper.acquireUniqueAlias(), criteria );
}
@Override
public <X> JpaCteCriteria<X> withRecursiveUnionAll(
AbstractQuery<X> baseCriteria,
Function<JpaCteCriteria<X>, AbstractQuery<X>> recursiveCriteriaProducer) {
return withInternal( Long.toString( System.nanoTime() ), baseCriteria, false, recursiveCriteriaProducer );
return withInternal( SqmCreationHelper.acquireUniqueAlias(), baseCriteria, false, recursiveCriteriaProducer );
}
@Override
public <X> JpaCteCriteria<X> withRecursiveUnionDistinct(
AbstractQuery<X> baseCriteria,
Function<JpaCteCriteria<X>, AbstractQuery<X>> recursiveCriteriaProducer) {
return withInternal( Long.toString( System.nanoTime() ), baseCriteria, true, recursiveCriteriaProducer );
return withInternal( SqmCreationHelper.acquireUniqueAlias(), baseCriteria, true, recursiveCriteriaProducer );
}
@Override

View File

@ -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;
@ -112,21 +113,21 @@ public abstract class AbstractSqmSelectQuery<T>
@Override
public <X> JpaCteCriteria<X> with(AbstractQuery<X> criteria) {
return withInternal( Long.toString( System.nanoTime() ), criteria );
return withInternal( SqmCreationHelper.acquireUniqueAlias(), criteria );
}
@Override
public <X> JpaCteCriteria<X> withRecursiveUnionAll(
AbstractQuery<X> baseCriteria,
Function<JpaCteCriteria<X>, AbstractQuery<X>> recursiveCriteriaProducer) {
return withInternal( Long.toString( System.nanoTime() ), baseCriteria, false, recursiveCriteriaProducer );
return withInternal( SqmCreationHelper.acquireUniqueAlias(), baseCriteria, false, recursiveCriteriaProducer );
}
@Override
public <X> JpaCteCriteria<X> withRecursiveUnionDistinct(
AbstractQuery<X> baseCriteria,
Function<JpaCteCriteria<X>, AbstractQuery<X>> recursiveCriteriaProducer) {
return withInternal( Long.toString( System.nanoTime() ), baseCriteria, true, recursiveCriteriaProducer );
return withInternal( SqmCreationHelper.acquireUniqueAlias(), baseCriteria, true, recursiveCriteriaProducer );
}
@Override