From e300bd89dd6cfa98a81969db8944a5ab9250083b Mon Sep 17 00:00:00 2001 From: "Greg L. Turnquist" Date: Wed, 22 Mar 2023 10:24:54 -0500 Subject: [PATCH] Drop FETCH from JOIN clauses when creating a count query in Hibernate. Resolves #2348. Supercedes #2686. --- .../repository/query/HqlQueryTransformer.java | 23 +++++++++++++++++++ .../query/HqlQueryTransformerTests.java | 10 ++++++++ 2 files changed, 33 insertions(+) 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 1b45d4e6a..906942f75 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 @@ -276,6 +276,29 @@ class HqlQueryTransformer extends HqlQueryRenderer { return tokens; } + @Override + public List visitJoin(HqlParser.JoinContext ctx) { + + List tokens = new ArrayList<>(); + + tokens.addAll(visit(ctx.joinType())); + tokens.add(new JpaQueryParsingToken(ctx.JOIN())); + + if (!countQuery) { + if (ctx.FETCH() != null) { + tokens.add(new JpaQueryParsingToken(ctx.FETCH())); + } + } + + tokens.addAll(visit(ctx.joinTarget())); + + if (ctx.joinRestriction() != null) { + tokens.addAll(visit(ctx.joinRestriction())); + } + + return tokens; + } + @Override public List visitAlias(HqlParser.AliasContext ctx) { 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 df1e8df65..6d33af2fe 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 @@ -903,6 +903,16 @@ class HqlQueryTransformerTests { } + @Test // GH-2348 + void removeFetchFromJoinsDuringCountQueryCreation() { + + assertCountQuery("select u from User u left outer join fetch u.roles r left outer JOIN FETCH u.accounts a", + "select count(u) from User u left outer join u.roles r left outer JOIN u.accounts a"); + + assertCountQuery("SELECT DISTINCT b FROM Board b LEFT JOIN FETCH b.comments ORDER BY b.id", + "SELECT count(DISTINCT b) FROM Board b LEFT JOIN b.comments"); + } + private void assertCountQuery(String originalQuery, String countQuery) { assertThat(createCountQueryFor(originalQuery)).isEqualTo(countQuery); }