If for some reason you want to order by using the ordinal position in JPA (e.g. ORDER BY 1,2,3), just use the CriteriaBuilder#literal(T) to specify the ordinal position, e.g:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
//you probably want to use the ordinal sorting only in multiselect/tuple queries as only then you control the column order
query.multiselect(column1Path, column2Path, columnNPath);
//some other query logic ...
int ordinalPositionToOrderBy = 1;
Expression ordinalPositionExpression = cb.literal(ordinalPositionToOrderBy);
Order order = cb.asc(ordinalPositionExpression)
query.orderBy(order);
After some thought it is not that surprising - the CriteriaBuilder#literal(T) simply passes the int literal to the ORDER BY clause which in effect gives the desired effect of ORDER BY 1 in the native SQL.
For me it turned out to be useful while working with the MS SQL Server and executing a SELECT DISTINCT ... query ordered by a sophisticated expression. The expected way of
Expression mySophisticatedOrderByExpression = /*...*/;
Order order = cb.asc(mySophisticatedOrderByExpression);
query.orderBy(order);
orderByExpression = order.getExpression();
query.multiselect(idPath, orderByExpression );
//... some more query logic
resulted in ORDER BY items must appear in the select list if SELECT DISTINCT is specified error message, although the expression extracted from the Orderwas passed to the query.multiselect(...) method. Switching to ordering by a cb.literal solved the issue.