Skip to content

Commit b577431

Browse files
committed
HHH-18378 Check where clause before reusing existing joins for fetch
1 parent 31d88e0 commit b577431

File tree

3 files changed

+45
-11
lines changed

3 files changed

+45
-11
lines changed

hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
import org.hibernate.query.sqm.tree.from.SqmJoin;
6464
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
6565
import org.hibernate.query.sqm.tree.from.SqmRoot;
66+
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
6667
import org.hibernate.query.sqm.tree.select.SqmOrderByClause;
6768
import org.hibernate.query.sqm.tree.select.SqmQueryPart;
6869
import org.hibernate.query.sqm.tree.select.SqmQuerySpec;
@@ -88,6 +89,7 @@
8889

8990
import static java.util.stream.Collectors.toList;
9091
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
92+
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
9193
import static org.hibernate.query.sqm.tree.jpa.ParameterCollector.collectParameters;
9294

9395
/**
@@ -215,6 +217,15 @@ public static boolean isFkOptimizationAllowed(SqmPath<?> sqmPath) {
215217
return false;
216218
}
217219

220+
public static List<NavigablePath> getWhereClauseNavigablePaths(SqmQuerySpec<?> querySpec) {
221+
final SqmWhereClause where = querySpec.getWhereClause();
222+
if ( where == null || where.getPredicate() == null ) {
223+
return Collections.emptyList();
224+
}
225+
226+
return collectNavigablePaths( List.of( where.getPredicate() ) );
227+
}
228+
218229
public static List<NavigablePath> getGroupByNavigablePaths(SqmQuerySpec<?> querySpec) {
219230
final List<SqmExpression<?>> expressions = querySpec.getGroupByClauseExpressions();
220231
if ( expressions.isEmpty() ) {
@@ -238,7 +249,7 @@ public static List<NavigablePath> getOrderByNavigablePaths(SqmQuerySpec<?> query
238249
}
239250

240251
private static List<NavigablePath> collectNavigablePaths(final List<SqmExpression<?>> expressions) {
241-
final List<NavigablePath> navigablePaths = new ArrayList<>( expressions.size() );
252+
final List<NavigablePath> navigablePaths = arrayList( expressions.size() );
242253
final SqmPathVisitor pathVisitor = new SqmPathVisitor( path -> navigablePaths.add( path.getNavigablePath() ) );
243254
for ( final SqmExpression<?> expression : expressions ) {
244255
if ( expression instanceof SqmAliasedNodeRef ) {

hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8192,7 +8192,10 @@ else if ( getLoadQueryInfluencers().hasEnabledFetchProfiles() ) {
81928192
joinProducer,
81938193
joinProducer.determineSqlJoinType( lhs, null, true )
81948194
);
8195-
if ( compatibleTableGroup == null ) {
8195+
final SqmQueryPart<?> queryPart = getCurrentSqmQueryPart();
8196+
if ( compatibleTableGroup == null
8197+
// If the compatible table group is used in the where clause it cannot be reused for fetching
8198+
|| ( queryPart != null && queryPart.getFirstQuerySpec().whereClauseContains( compatibleTableGroup.getNavigablePath(), this ) ) ) {
81968199
final TableGroupJoin tableGroupJoin = joinProducer.createTableGroupJoin(
81978200
fetchablePath,
81988201
lhs,

hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQuerySpec.java

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -629,15 +629,26 @@ public void appendHqlString(StringBuilder sb) {
629629
super.appendHqlString( sb );
630630
}
631631

632+
@Internal
633+
public boolean whereClauseContains(NavigablePath navigablePath, SqmToSqlAstConverter sqlAstConverter) {
634+
if ( whereClause == null ) {
635+
return false;
636+
}
637+
return isSameOrParent(
638+
navigablePath,
639+
sqlAstConverter.resolveMetadata( this, SqmUtil::getWhereClauseNavigablePaths )
640+
);
641+
}
642+
632643
@Internal
633644
public boolean groupByClauseContains(NavigablePath navigablePath, SqmToSqlAstConverter sqlAstConverter) {
634645
if ( groupByClauseExpressions.isEmpty() ) {
635646
return false;
636647
}
637-
return navigablePathsContain( sqlAstConverter.resolveMetadata(
638-
this,
639-
SqmUtil::getGroupByNavigablePaths
640-
), navigablePath );
648+
return isSameOrChildren(
649+
navigablePath,
650+
sqlAstConverter.resolveMetadata( this, SqmUtil::getGroupByNavigablePaths )
651+
);
641652
}
642653

643654
@Internal
@@ -646,18 +657,27 @@ public boolean orderByClauseContains(NavigablePath navigablePath, SqmToSqlAstCon
646657
if ( orderByClause == null || orderByClause.getSortSpecifications().isEmpty() ) {
647658
return false;
648659
}
649-
return navigablePathsContain( sqlAstConverter.resolveMetadata(
650-
this,
651-
SqmUtil::getOrderByNavigablePaths
652-
), navigablePath );
660+
return isSameOrChildren(
661+
navigablePath,
662+
sqlAstConverter.resolveMetadata( this, SqmUtil::getOrderByNavigablePaths )
663+
);
653664
}
654665

655-
private boolean navigablePathsContain(List<NavigablePath> navigablePaths, NavigablePath navigablePath) {
666+
private boolean isSameOrChildren(NavigablePath navigablePath, List<NavigablePath> navigablePaths) {
656667
for ( NavigablePath path : navigablePaths ) {
657668
if ( path.isParentOrEqual( navigablePath ) ) {
658669
return true;
659670
}
660671
}
661672
return false;
662673
}
674+
675+
private boolean isSameOrParent(NavigablePath navigablePath, List<NavigablePath> navigablePaths) {
676+
for ( NavigablePath path : navigablePaths ) {
677+
if ( navigablePath.isParentOrEqual( path ) ) {
678+
return true;
679+
}
680+
}
681+
return false;
682+
}
663683
}

0 commit comments

Comments
 (0)