diff --git a/extensions/panache/panache-hibernate-common/runtime/src/main/java/io/quarkus/panache/hibernate/common/runtime/PanacheJpaUtil.java b/extensions/panache/panache-hibernate-common/runtime/src/main/java/io/quarkus/panache/hibernate/common/runtime/PanacheJpaUtil.java index 3f1c2d22752d79..3029a33398242c 100644 --- a/extensions/panache/panache-hibernate-common/runtime/src/main/java/io/quarkus/panache/hibernate/common/runtime/PanacheJpaUtil.java +++ b/extensions/panache/panache-hibernate-common/runtime/src/main/java/io/quarkus/panache/hibernate/common/runtime/PanacheJpaUtil.java @@ -61,7 +61,7 @@ public static String createFindQuery(Class entityClass, String query, int par return "FROM " + getEntityName(entityClass); } - String trimmed = query.trim(); + String trimmed = query.replace('\n', ' ').replace('\r', ' ').trim(); if (trimmed.isEmpty()) { return "FROM " + getEntityName(entityClass); } diff --git a/integration-tests/hibernate-orm-panache-kotlin/src/main/kotlin/io/quarkus/it/panache/kotlin/TestEndpoint.kt b/integration-tests/hibernate-orm-panache-kotlin/src/main/kotlin/io/quarkus/it/panache/kotlin/TestEndpoint.kt index fa1bb50df7c41b..42ff7b0990706b 100644 --- a/integration-tests/hibernate-orm-panache-kotlin/src/main/kotlin/io/quarkus/it/panache/kotlin/TestEndpoint.kt +++ b/integration-tests/hibernate-orm-panache-kotlin/src/main/kotlin/io/quarkus/it/panache/kotlin/TestEndpoint.kt @@ -5,6 +5,7 @@ import io.quarkus.panache.common.Page import io.quarkus.panache.common.Parameters import io.quarkus.panache.common.Sort import io.quarkus.panache.common.exception.PanacheQueryException +import io.quarkus.runtime.annotations.RegisterForReflection import jakarta.inject.Inject import jakarta.persistence.LockModeType import jakarta.persistence.NoResultException @@ -1091,4 +1092,47 @@ class TestEndpoint { return "OK" } + + @GET + @Path("project") + @Transactional + fun testProject(): String { + @RegisterForReflection + data class MyProjection( + val projectedName: String + ) + + val mark = Person() + mark.name = "Mark" + mark.persistAndFlush() + + val hqlWithoutSpace = """ + select + name as projectedName + from + io.quarkus.it.panache.kotlin.Person + where + name = ?1 + """.trimIndent() + val withoutSpace = Person.find(hqlWithoutSpace, "Mark").project(MyProjection::class.java).firstResult() + Assertions.assertNotNull(withoutSpace) + Assertions.assertEquals(mark.name, withoutSpace?.projectedName) + + // There is a space behind "select " + val hqlWithSpace = """ + select + name as projectedName + from + io.quarkus.it.panache.kotlin.Person + where + name = ?1 + """.trimIndent() + val withSpace = Person.find(hqlWithSpace, "Mark").project(MyProjection::class.java).firstResult() + Assertions.assertNotNull(withSpace) + Assertions.assertEquals(mark.name, withSpace?.projectedName) + + Person.deleteAll() + + return "OK" + } } diff --git a/integration-tests/hibernate-orm-panache-kotlin/src/test/kotlin/io/quarkus/it/panache/ProjectionTest.kt b/integration-tests/hibernate-orm-panache-kotlin/src/test/kotlin/io/quarkus/it/panache/ProjectionTest.kt new file mode 100644 index 00000000000000..bdacd91f12281a --- /dev/null +++ b/integration-tests/hibernate-orm-panache-kotlin/src/test/kotlin/io/quarkus/it/panache/ProjectionTest.kt @@ -0,0 +1,21 @@ +package io.quarkus.it.panache + +import io.quarkus.test.junit.QuarkusIntegrationTest +import io.quarkus.test.junit.QuarkusTest +import io.restassured.RestAssured +import org.hamcrest.Matchers +import org.junit.jupiter.api.Test + +// Native tests +@QuarkusIntegrationTest +class ProjectionIT : ProjectionTest() + +// Quarkus/JVM tests +@QuarkusTest +open class ProjectionTest { + + @Test + fun testProject() { + RestAssured.`when`()["/test/project"].then().body(Matchers.`is`("OK")) + } +} 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 3ea97d484cc464..12bd60f7b4a24a 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 @@ -38,6 +38,7 @@ import io.quarkus.panache.common.Parameters; import io.quarkus.panache.common.Sort; import io.quarkus.panache.common.exception.PanacheQueryException; +import io.quarkus.runtime.annotations.RegisterForReflection; /** * Various tests covering Panache functionality. All tests should work in both standard JVM and in native mode. @@ -1642,4 +1643,47 @@ public String testEnhancement27184DeleteDetached() { return "OK"; } + + @RegisterForReflection + static class MyProjection { + String projectedName; + } + + @GET + @Path("project") + @Transactional + public String testPanacheProject() { + var mark = new Person(); + mark.name = "Mark"; + mark.persistAndFlush(); + + var hqlWithoutSpace = """ + select + name as projectedName + from + io.quarkus.it.panache.kotlin.Person + where + name = ?1 + """; + var persistedWithoutSpace = Person.find(hqlWithoutSpace, "Mark").project(MyProjection.class).firstResult(); + Assertions.assertNotNull(persistedWithoutSpace); + Assertions.assertEquals(mark.name, persistedWithoutSpace.projectedName); + + // We need to escape the whitespace in Java otherwise the compiler removes it. + var hqlWithSpace = """ + select\s + name as projectedName + from + io.quarkus.it.panache.kotlin.Person + where + name = ?1 + """; + var persistedWithSpace = Person.find(hqlWithSpace, "Mark").project(MyProjection.class).firstResult(); + Assertions.assertNotNull(persistedWithSpace); + Assertions.assertEquals(mark.name, persistedWithSpace.projectedName); + + Person.deleteAll(); + + return "OK"; + } } diff --git a/integration-tests/hibernate-orm-panache/src/test/java/io/quarkus/it/panache/PanacheFunctionalityTest.java b/integration-tests/hibernate-orm-panache/src/test/java/io/quarkus/it/panache/PanacheFunctionalityTest.java index 92aa37c3dccfe5..bf0b00e5216cb3 100644 --- a/integration-tests/hibernate-orm-panache/src/test/java/io/quarkus/it/panache/PanacheFunctionalityTest.java +++ b/integration-tests/hibernate-orm-panache/src/test/java/io/quarkus/it/panache/PanacheFunctionalityTest.java @@ -238,4 +238,9 @@ Person getBug7102(Long id) { public void testEnhancement27184DeleteDetached() { RestAssured.when().get("/test/testEnhancement27184DeleteDetached").then().body(is("OK")); } + + @Test + public void testProjectionWithTextBlocks() { + RestAssured.when().get("/test/project").then().body(is("OK")); + } }