From efc9aed64ec659192e9482657f5becdbcc9084ab Mon Sep 17 00:00:00 2001 From: "Greg L. Turnquist" Date: Mon, 20 Mar 2023 17:05:24 -0500 Subject: [PATCH] Count query generation should handle missing alias. In the event of a Hibernate query where the FROM clause has no alias, the query parser should use "__" as a stand-in alias. Resolves #2032. Related: #2220. --- .../jpa/repository/query/HqlQueryTransformer.java | 11 +++++++++++ .../jpa/repository/query/JpaQueryParsingToken.java | 5 ++++- .../repository/query/HqlQueryTransformerTests.java | 10 ++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlQueryTransformer.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlQueryTransformer.java index dbb0f9155..1b45d4e6a 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlQueryTransformer.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/HqlQueryTransformer.java @@ -243,6 +243,17 @@ class HqlQueryTransformer extends HqlQueryRenderer { if (this.alias == null && !isSubquery(ctx)) { this.alias = tokens.get(tokens.size() - 1).getToken(); } + } else { + + if (countQuery) { + + tokens.add(TOKEN_AS); + tokens.add(TOKEN_DOUBLE_UNDERSCORE); + + if (this.alias == null && !isSubquery(ctx)) { + this.alias = TOKEN_DOUBLE_UNDERSCORE.getToken(); + } + } } } else if (ctx.subquery() != null) { diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryParsingToken.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryParsingToken.java index 5c221e62d..e4ca63df2 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryParsingToken.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryParsingToken.java @@ -17,7 +17,6 @@ package org.springframework.data.jpa.repository.query; import java.util.List; import java.util.function.Supplier; -import java.util.stream.Collectors; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNode; @@ -53,6 +52,10 @@ class JpaQueryParsingToken { public static final JpaQueryParsingToken TOKEN_CLOSE_SQUARE_BRACKET_BRACE = new JpaQueryParsingToken("]}"); public static final JpaQueryParsingToken TOKEN_CLOSE_PAREN_BRACE = new JpaQueryParsingToken(")}"); + public static final JpaQueryParsingToken TOKEN_DOUBLE_UNDERSCORE = new JpaQueryParsingToken("__"); + + public static final JpaQueryParsingToken TOKEN_AS = new JpaQueryParsingToken("AS"); + public static final JpaQueryParsingToken TOKEN_DESC = new JpaQueryParsingToken("desc", false); public static final JpaQueryParsingToken TOKEN_ASC = new JpaQueryParsingToken("asc", false); diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/HqlQueryTransformerTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/HqlQueryTransformerTests.java index b3a6bcf40..cae0d71d3 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/HqlQueryTransformerTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/HqlQueryTransformerTests.java @@ -798,6 +798,16 @@ class HqlQueryTransformerTests { assertThat(alias("select u from User as u left join u.roles as r")).isEqualTo("u"); } + @Test // GH-2032 + void countQueryShouldWorkEvenWithoutExplicitAlias() { + + assertCountQuery("FROM BookError WHERE portal = :portal", + "select count(__) FROM BookError AS __ WHERE portal = :portal"); + + assertCountQuery("FROM BookError b WHERE portal = :portal", + "select count(b) FROM BookError b WHERE portal = :portal"); + } + private void assertCountQuery(String originalQuery, String countQuery) { assertThat(createCountQueryFor(originalQuery)).isEqualTo(countQuery); }