@@ -865,30 +865,25 @@ public Map<JpaCriteriaParameter<?>, SqmJpaCriteriaParameterWrapper<?>> getJpaCri
865
865
866
866
public static SqmSortSpecification sortSpecification (SqmSelectStatement <?> sqm , Order <?> order ) {
867
867
final List <SqmSelectableNode <?>> items = sqm .getQuerySpec ().getSelectClause ().getSelectionItems ();
868
- final int element = order .getElement ();
869
- if ( element < 1 ) {
870
- throw new IllegalQueryOperationException ("Cannot order by element " + element
871
- + " (the first select item is element 1)" );
872
- }
873
- if ( element > items .size () ) {
874
- throw new IllegalQueryOperationException ("Cannot order by element " + element
875
- + " (there are only " + items .size () + " select items)" );
876
- }
877
- final SqmSelectableNode <?> selected = items .get ( element -1 );
868
+ final SqmSelectableNode <?> selected = selectedNode ( sqm , order ); // does validation by side effect!
869
+ return createSortSpecification ( sqm , order , items , selected );
870
+ }
878
871
872
+ private static SqmSortSpecification createSortSpecification (
873
+ SqmSelectStatement <?> sqm , Order <?> order , List <SqmSelectableNode <?>> items , SqmSelectableNode <?> selected ) {
879
874
final NodeBuilder builder = sqm .nodeBuilder ();
880
875
if ( order .getEntityClass () == null ) {
881
876
// ordering by an element of the select list
882
877
return new SqmSortSpecification (
883
- new SqmAliasedNodeRef ( element , builder .getIntegerType (), builder ),
878
+ new SqmAliasedNodeRef ( order . getElement () , builder .getIntegerType (), builder ),
884
879
order .getDirection (),
885
880
order .getNullPrecedence (),
886
881
order .isCaseInsensitive ()
887
882
);
888
883
}
889
884
else {
890
885
// ordering by an attribute of the returned entity
891
- if ( items .size () = = 1 ) {
886
+ if ( items .size () < = 1 ) {
892
887
if ( selected instanceof SqmFrom <?, ?> root ) {
893
888
if ( !order .getEntityClass ().isAssignableFrom ( root .getJavaType () ) ) {
894
889
throw new IllegalQueryOperationException ("Select item was of wrong entity type" );
@@ -898,7 +893,10 @@ public static SqmSortSpecification sortSpecification(SqmSelectStatement<?> sqm,
898
893
while ( tokens .hasMoreTokens () ) {
899
894
path = path .get ( tokens .nextToken () );
900
895
}
901
- return builder .sort ( path , order .getDirection (), order .getNullPrecedence (), order .isCaseInsensitive () );
896
+ return builder .sort ( path ,
897
+ order .getDirection (),
898
+ order .getNullPrecedence (),
899
+ order .isCaseInsensitive () );
902
900
}
903
901
else {
904
902
throw new IllegalQueryOperationException ("Select item was not an entity type" );
@@ -910,6 +908,32 @@ public static SqmSortSpecification sortSpecification(SqmSelectStatement<?> sqm,
910
908
}
911
909
}
912
910
911
+ private static SqmSelectableNode <?> selectedNode (SqmSelectStatement <?> sqm , Order <?> order ) {
912
+ final int element = order .getElement ();
913
+ if ( element < 1 ) {
914
+ throw new IllegalQueryOperationException ("Cannot order by element " + element
915
+ + " (the first select item is element 1)" );
916
+ }
917
+ final var selectionItems = sqm .getQuerySpec ().getSelectClause ().getSelectionItems ();
918
+ final int items = selectionItems .size ();
919
+ if ( items == 0 && element == 1 ) {
920
+ if ( order .getEntityClass () == null || sqm .getQuerySpec ().getRootList ().size () > 1 ) {
921
+ throw new IllegalQueryOperationException ("Cannot order by element " + element
922
+ + " (there is no select list)" );
923
+ }
924
+ else {
925
+ return sqm .getQuerySpec ().getRootList ().get (0 );
926
+ }
927
+ }
928
+ else if ( element > items ) {
929
+ throw new IllegalQueryOperationException ( "Cannot order by element " + element
930
+ + " (there are only " + items + " select items)" );
931
+ }
932
+ else {
933
+ return selectionItems .get ( element - 1 );
934
+ }
935
+ }
936
+
913
937
public static boolean isSelectionAssignableToResultType (SqmSelection <?> selection , Class <?> expectedResultType ) {
914
938
if ( expectedResultType == null ) {
915
939
return true ;
0 commit comments