From 287104c2e3dea25c3f7514f27d255fe191267c92 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Sun, 4 Sep 2016 18:47:22 +0200 Subject: [PATCH] DATAJPA-960 - Fixed alias detection for queries not containing an alias. We're now more lenient against manually defined queries that do not contain aliases when adding order by clauses to them. The alias detection now doesn't accidentally pick up "where" anymore in case no primary alias is declared and the code applying the order by clause only qualifies the expressions created if there actually is an alias in the first place. --- .../data/jpa/repository/query/QueryUtils.java | 8 ++++---- .../data/jpa/repository/query/QueryUtilsUnitTests.java | 9 +++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java b/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java index 4e2bb80f0..3825b10dd 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java @@ -110,7 +110,7 @@ public abstract class QueryUtils { builder.append(IDENTIFIER_GROUP); // Entity name, can be qualified (any builder.append("(?:\\sas)*"); // exclude possible "as" keyword builder.append("(?:\\s)+"); // at least one space separating - builder.append("(\\w*)"); // the actual alias + builder.append("(?!(?:where))(\\w*)"); // the actual alias ALIAS_MATCH = compile(builder.toString(), CASE_INSENSITIVE); @@ -199,8 +199,7 @@ public abstract class QueryUtils { * @return */ public static String applySorting(String query, Sort sort) { - - return applySorting(query, sort, DEFAULT_ALIAS); + return applySorting(query, sort, detectAlias(query)); } /** @@ -259,7 +258,8 @@ public abstract class QueryUtils { } } - String reference = qualifyReference ? String.format("%s.%s", alias, property) : property; + String reference = qualifyReference && StringUtils.hasText(alias) ? String.format("%s.%s", alias, property) + : property; String wrapped = order.isIgnoreCase() ? String.format("lower(%s)", reference) : reference; return String.format("%s %s", wrapped, toJpaDirection(order)); diff --git a/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java index 939b6fcbe..30ca4f28a 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java @@ -352,6 +352,15 @@ public class QueryUtilsUnitTests { assertThat(hasConstructorExpression("select new foo.bar.FooBar(\na.id) from DtoA a "), is(true)); } + /** + * @see DATAJPA-960 + */ + @Test + public void doesNotQualifySortIfNoAliasDetected() { + assertThat(applySorting("from mytable where ?1 is null", new Sort("firstname")), + endsWith("order by firstname asc")); + } + private static void assertCountQuery(String originalQuery, String countQuery) { assertThat(createCountQueryFor(originalQuery), is(countQuery)); }