diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index bd086224f9..2cbb5f024e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -2338,7 +2338,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base sqmPosition = aliasedNodeOrdinal - 1; path = aliasedNodeRef.getNavigablePath(); } - else if ( statement.getQuerySource() == SqmQuerySource.CRITERIA ) { + else if ( statement.getQuerySource() == SqmQuerySource.CRITERIA && currentClauseStack.getCurrent() != Clause.OVER ) { // In JPA Criteria we could be using the same expression object for the group/order by and select item // We try to find the select item position for this expression here which is not necessarily just an optimization. // This is vital to enable the support for parameters in these expressions. diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaWindowFunctionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaWindowFunctionTest.java index 49d3cd649c..3dba2892db 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaWindowFunctionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/criteria/CriteriaWindowFunctionTest.java @@ -21,6 +21,7 @@ import org.hibernate.testing.orm.domain.StandardDomainModel; import org.hibernate.testing.orm.domain.gambit.EntityOfBasics; import org.hibernate.testing.orm.junit.DialectFeatureChecks; import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.Jira; import org.hibernate.testing.orm.junit.RequiresDialectFeature; import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.SessionFactory; @@ -134,6 +135,48 @@ public class CriteriaWindowFunctionTest { ); } + @Test + @Jira( "https://hibernate.atlassian.net/browse/HHH-17391" ) + public void testRowNumberMultiSelectGroupBy(final SessionFactoryScope scope) { + scope.inTransaction( + session -> { + final HibernateCriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery( Tuple.class ); + final Root root = cr.from( EntityOfBasics.class ); + + final JpaWindow window = cb.createWindow(); + window.partitionBy( root.get( "id" ) ).orderBy( cb.asc( root.get( "id" ) ) ); + final JpaExpression rowNumber = cb.rowNumber( window ); + + cr.multiselect( root.get( "id" ), rowNumber ).groupBy( root.get( "id" ) ); + final List resultList = session.createQuery( cr ).getResultList(); + assertEquals( 5, resultList.size() ); + resultList.forEach( tuple -> assertEquals( 1L, tuple.get( 1, Long.class ) ) ); + } + ); + } + + @Test + @Jira( "https://hibernate.atlassian.net/browse/HHH-17392" ) + public void testRowNumberMultiSelect(final SessionFactoryScope scope) { + scope.inTransaction( + session -> { + final HibernateCriteriaBuilder cb = session.getCriteriaBuilder(); + final CriteriaQuery cr = cb.createQuery( Tuple.class ); + final Root root = cr.from( EntityOfBasics.class ); + + final JpaWindow window = cb.createWindow(); + window.partitionBy( root.get( "id" ) ).orderBy( cb.asc( root.get( "id" ) ) ); + final JpaExpression rowNumber = cb.rowNumber( window ); + + cr.multiselect( root.get( "id" ), rowNumber ); + final List resultList = session.createQuery( cr ).getResultList(); + assertEquals( 5, resultList.size() ); + resultList.forEach( tuple -> assertEquals( 1L, tuple.get( 1, Long.class ) ) ); + } + ); + } + @Test public void testFirstValue(SessionFactoryScope scope) { scope.inTransaction(