From 513df597a510cc2eb9154ebf1a989af843e574d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Mathieu?= Date: Fri, 3 Jul 2020 12:45:51 +0200 Subject: [PATCH] Implements count() for named queries Fixes #10319 --- .../runtime/CommonPanacheQueryImpl.java | 24 ++++++++++--------- .../io/quarkus/it/panache/TestEndpoint.java | 1 + 2 files changed, 14 insertions(+), 11 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 4a5cd99105a0a..c0fa321b1d5b1 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 @@ -206,12 +206,14 @@ public void withHint(String hintName, Object value) { @SuppressWarnings("unchecked") public long count() { - if (AbstractJpaOperations.isNamedQuery(query)) { - throw new PanacheQueryException("Unable to perform a count operation on a named query"); - } - if (count == null) { - Query countQuery = em.createQuery(countQuery()); + String selectQuery = query; + if (AbstractJpaOperations.isNamedQuery(query)) { + org.hibernate.query.Query q = (org.hibernate.query.Query) em.createNamedQuery(query.substring(1)); + selectQuery = q.getQueryString(); + } + + Query countQuery = em.createQuery(countQuery(selectQuery)); if (paramsArrayOrMap instanceof Map) AbstractJpaOperations.bindParameters(countQuery, (Map) paramsArrayOrMap); else @@ -223,13 +225,13 @@ public long count() { return count; } - private String countQuery() { + private String countQuery(String selectQuery) { if (countQuery != null) { return countQuery; } // try to generate a good count query from the existing query - Matcher selectMatcher = SELECT_PATTERN.matcher(query); + Matcher selectMatcher = SELECT_PATTERN.matcher(selectQuery); String countQuery; if (selectMatcher.matches()) { // this one cannot be null @@ -239,17 +241,17 @@ private String countQuery() { String secondSelection = selectMatcher.group(2); // we can only count distinct single columns if (secondSelection != null && !secondSelection.trim().isEmpty()) { - throw new PanacheQueryException("Count query not supported for select query: " + query); + throw new PanacheQueryException("Count query not supported for select query: " + selectQuery); } countQuery = "SELECT COUNT(" + firstSelection + ") " + selectMatcher.group(3); } else { // it's not distinct, forget the column list countQuery = "SELECT COUNT(*) " + selectMatcher.group(3); } - } else if (FROM_PATTERN.matcher(query).matches()) { - countQuery = "SELECT COUNT(*) " + query; + } else if (FROM_PATTERN.matcher(selectQuery).matches()) { + countQuery = "SELECT COUNT(*) " + selectQuery; } else { - throw new PanacheQueryException("Count query not supported for select query: " + query); + throw new PanacheQueryException("Count query not supported for select query: " + selectQuery); } // remove the order by clause 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 2f5ecc52d0d90..971a987404c7c 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 @@ -159,6 +159,7 @@ public String testModel() { persons = Person.find("#Person.getByName", Parameters.with("name", "stef")).list(); Assertions.assertEquals(1, persons.size()); Assertions.assertEquals(person, persons.get(0)); + Assertions.assertEquals(1, Person.find("#Person.getByName", Parameters.with("name", "stef")).count()); Assertions.assertThrows(PanacheQueryException.class, () -> Person.find("#Person.namedQueryNotFound").list()); NamedQueryEntity.find("#NamedQueryMappedSuperClass.getAll").list(); NamedQueryEntity.find("#NamedQueryEntity.getAll").list();