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 a5e22e7ea..351a08f29 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 @@ -132,7 +132,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("(?!(?:where))(\\w*)"); // the actual alias + builder.append("(?!(?:where))(\\w+)"); // the actual alias ALIAS_MATCH = compile(builder.toString(), CASE_INSENSITIVE); @@ -544,7 +544,8 @@ public abstract class QueryUtils { Assert.hasText(query, "Query must not be null or empty!"); Matcher matcher = PROJECTION_CLAUSE.matcher(query); - return matcher.find() ? matcher.group(1) : ""; + String projection = matcher.find() ? matcher.group(1) : ""; + return projection.trim(); } /** diff --git a/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java index 12d13b00c..1024ba18c 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java @@ -152,7 +152,7 @@ class StringQuery implements DeclaredQuery { */ @Override public boolean isDefaultProjection() { - return getProjection().equals(alias); + return getProjection().equalsIgnoreCase(alias); } /* diff --git a/src/test/java/org/springframework/data/jpa/repository/query/StringQueryUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/StringQueryUnitTests.java index 96a78a8ad..79226afed 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/StringQueryUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/StringQueryUnitTests.java @@ -340,7 +340,12 @@ public class StringQueryUnitTests { checkAlias("SELECT FROM USER U", "U", "uppercase"); checkAlias("select u from User u", "u", "simple query"); checkAlias("select u from com.acme.User u", "u", "fully qualified package name"); - checkAlias("select u from T05User u", "u", "intersting entity name"); + checkAlias("select u from T05User u", "u", "interesting entity name"); + checkAlias("from User ", null, "trailing space"); + checkAlias("from User", null, "no trailing space"); + checkAlias("from User as bs", "bs", "ignored as"); + checkAlias("from User as AS", "AS", "ignored as using the second"); + checkAlias("from User asas", "asas", "asas is weird but legal"); softly.assertAll(); } @@ -470,6 +475,43 @@ public class StringQueryUnitTests { softly.assertAll(); } + @Test // DATAJPA-1318 + public void isNotDefaultProjection() { + + List queriesWithoutDefaultProjection = Arrays.asList( // + "select a, b from C as c", // + "SELECT a, b FROM C as c", // + "SELECT a, b FROM C", // + "SELECT a, b FROM C ", // + "select a, b from C ", // + "select a, b from C"); + + for (String queryString : queriesWithoutDefaultProjection) { + softly.assertThat(new StringQuery(queryString).isDefaultProjection()) // + .describedAs(queryString) // + .isFalse(); + } + + List queriesWithDefaultProjection = Arrays.asList( // + "select c from C as c", // + "SELECT c FROM C as c", // + "SELECT c FROM C as c ", // + "SELECT c FROM C as c", // + "SELECT c FROM C as c", // + "SELECT c FROM C as C", // + "SELECT C FROM C as c", // + "SELECT C FROM C as C" // + ); + + for (String queryString : queriesWithDefaultProjection) { + softly.assertThat(new StringQuery(queryString).isDefaultProjection()) // + .describedAs(queryString) // + .isTrue(); + } + + softly.assertAll(); + } + public void checkNumberOfNamedParameters(String query, int expectedSize, String label) { DeclaredQuery declaredQuery = DeclaredQuery.of(query);