From e6164cabfc27cc316e2f675e71ac779896f8c9d2 Mon Sep 17 00:00:00 2001 From: Davide D'Alto Date: Mon, 7 Nov 2022 16:05:28 +0000 Subject: [PATCH 1/2] [#29089] Fix error with projections in Panache When trying to run a select distinct query with projection, Panache will lowercase the field names. --- .../orm/panache/common/runtime/CommonPanacheQueryImpl.java | 7 +++---- .../panache/common/runtime/CommonPanacheQueryImpl.java | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/extensions/panache/hibernate-orm-panache-common/runtime/src/main/java/io/quarkus/hibernate/orm/panache/common/runtime/CommonPanacheQueryImpl.java b/extensions/panache/hibernate-orm-panache-common/runtime/src/main/java/io/quarkus/hibernate/orm/panache/common/runtime/CommonPanacheQueryImpl.java index 894357ec8a09e..70bfb1a803373 100644 --- a/extensions/panache/hibernate-orm-panache-common/runtime/src/main/java/io/quarkus/hibernate/orm/panache/common/runtime/CommonPanacheQueryImpl.java +++ b/extensions/panache/hibernate-orm-panache-common/runtime/src/main/java/io/quarkus/hibernate/orm/panache/common/runtime/CommonPanacheQueryImpl.java @@ -95,15 +95,14 @@ public CommonPanacheQueryImpl project(Class type) { int endSelect = lowerCasedTrimmedQuery.indexOf(" from "); String trimmedQuery = query.trim(); // 7 is the length of "select " - String selectClause = trimmedQuery.substring(7, endSelect); + String selectClause = trimmedQuery.substring(7, endSelect).trim(); String from = trimmedQuery.substring(endSelect); StringBuilder newQuery = new StringBuilder("select "); // Handle select-distinct. HQL example: select distinct new org.acme.ProjectionClass... - String lowerCasedTrimmedSelect = selectClause.trim().toLowerCase(); - boolean distinctQuery = lowerCasedTrimmedSelect.startsWith("distinct "); + boolean distinctQuery = selectClause.toLowerCase().startsWith("distinct "); if (distinctQuery) { // 9 is the length of "distinct " - selectClause = lowerCasedTrimmedSelect.substring(9).trim(); + selectClause = selectClause.substring(9).trim(); newQuery.append("distinct "); } diff --git a/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/CommonPanacheQueryImpl.java b/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/CommonPanacheQueryImpl.java index 3623f2ee25cdf..96896088c52b0 100644 --- a/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/CommonPanacheQueryImpl.java +++ b/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/CommonPanacheQueryImpl.java @@ -82,15 +82,14 @@ public CommonPanacheQueryImpl project(Class type) { int endSelect = lowerCasedTrimmedQuery.indexOf(" from "); String trimmedQuery = query.trim(); // 7 is the length of "select " - String selectClause = trimmedQuery.substring(7, endSelect); + String selectClause = trimmedQuery.substring(7, endSelect).trim(); String from = trimmedQuery.substring(endSelect); StringBuilder newQuery = new StringBuilder("select "); // Handle select-distinct. HQL example: select distinct new org.acme.ProjectionClass... - String lowerCasedTrimmedSelect = selectClause.trim().toLowerCase(); - boolean distinctQuery = lowerCasedTrimmedSelect.startsWith("distinct "); + boolean distinctQuery = selectClause.toLowerCase().startsWith("distinct "); if (distinctQuery) { // 9 is the length of "distinct " - selectClause = lowerCasedTrimmedSelect.substring(9).trim(); + selectClause = selectClause.substring(9).trim(); newQuery.append("distinct "); } From 9becd8a405673589c9bfbe00976ef0558fced3bc Mon Sep 17 00:00:00 2001 From: Davide D'Alto Date: Thu, 10 Nov 2022 15:39:24 +0000 Subject: [PATCH 2/2] [#29089] Test for Panache Reactive and ORM --- .../java/io/quarkus/it/panache/TestEndpoint.java | 12 ++++++++++++ .../io/quarkus/it/panache/reactive/TestEndpoint.java | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/integration-tests/hibernate-orm-panache/src/main/java/io/quarkus/it/panache/TestEndpoint.java b/integration-tests/hibernate-orm-panache/src/main/java/io/quarkus/it/panache/TestEndpoint.java index 2641e034de2b3..363fd589281d4 100644 --- a/integration-tests/hibernate-orm-panache/src/main/java/io/quarkus/it/panache/TestEndpoint.java +++ b/integration-tests/hibernate-orm-panache/src/main/java/io/quarkus/it/panache/TestEndpoint.java @@ -1253,6 +1253,18 @@ public String testProjection() { long countDistinct = projectionDistinctQuery.count(); Assertions.assertEquals(1L, countDistinct); + // We are checking that not everything gets lowercased + PanacheQuery letterCaseQuery = Cat + // The spaces at the beginning are intentional + .find(" SELECT disTINct 'GARFIELD', 'JoN ArBuCkLe' from Cat c where name = :NamE group by name ", + Parameters.with("NamE", bubulle.name)) + .project(CatProjectionBean.class); + + CatProjectionBean catView = letterCaseQuery.firstResult(); + // Must keep the letter case + Assertions.assertEquals("GARFIELD", catView.getName()); + Assertions.assertEquals("JoN ArBuCkLe", catView.getOwnerName()); + Cat.deleteAll(); CatOwner.deleteAll(); diff --git a/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/TestEndpoint.java b/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/TestEndpoint.java index fb50b9a4287b4..7046f84404eb3 100644 --- a/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/TestEndpoint.java +++ b/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/TestEndpoint.java @@ -1675,6 +1675,16 @@ public Uni testProjection2() { Assertions.assertTrue( exception.getMessage().startsWith("Unable to perform a projection on a 'select new' query")); }) + .chain(() -> Cat + .find(" SELECT disTINct 'GARFIELD', 'JoN ArBuCkLe' from Cat c where name = :NamE group by name ", + Parameters.with("NamE", catName)) + .project(CatProjectionBean.class) + . firstResult()) + .invoke(catView -> { + // Must keep the letter case + Assertions.assertEquals("GARFIELD", catView.name); + Assertions.assertEquals("JoN ArBuCkLe", catView.ownerName); + }) .replaceWith("OK"); }