diff --git a/docs/src/main/asciidoc/hibernate-orm-panache.adoc b/docs/src/main/asciidoc/hibernate-orm-panache.adoc index 06b91e4d7a61f3..7f960f655f001b 100644 --- a/docs/src/main/asciidoc/hibernate-orm-panache.adoc +++ b/docs/src/main/asciidoc/hibernate-orm-panache.adoc @@ -939,31 +939,31 @@ PanacheQuery query = Dog.findAll().project(DogDto.class); ---- <1> The `ownerName` DTO constructor's parameter will be loaded from the `owner.name` HQL property. -In case you want to project nested class like Person in Dog entity you can use `@NestedProjectedClass` annotation on projected class. +In case you want to project an entity in a class with nested classes, you can use the `@NestedProjectedClass` annotation on those nested classes. [source,java] ---- @RegisterForReflection -public class DogDto2 { +public class DogDto { public String name; - public PersonDto2 owner; + public PersonDto owner; - public DogDto2(String name, PersonDto2 owner) { + public DogDto(String name, PersonDto owner) { this.name = name; this.owner = owner; } @NestedProjectedClass // <1> - public static class PersonDto2 { + public static class PersonDto { public String name; - public PersonDto2(String name) { + public PersonDto(String name) { this.name = name; } } } -PanacheQuery query = Dog.findAll().project(DogDto2.class); +PanacheQuery query = Dog.findAll().project(DogDto.class); ---- <1> This annotation can be used when you want to project `@Embedded` entity or `@ManyToOne`, `@OneToOne` relation. diff --git a/docs/src/main/asciidoc/hibernate-reactive-panache.adoc b/docs/src/main/asciidoc/hibernate-reactive-panache.adoc index 23ff16d587b509..c57ded40ed7314 100644 --- a/docs/src/main/asciidoc/hibernate-reactive-panache.adoc +++ b/docs/src/main/asciidoc/hibernate-reactive-panache.adoc @@ -690,7 +690,7 @@ PanacheQuery query = Dog.findAll().project(DogDto.class); ---- <1> The `ownerName` DTO constructor's parameter will be loaded from the `owner.name` HQL property. -In case you want to project nested class like Person in Dog entity you can use `@NestedProjectedClass` annotation on projected class. +In case you want to project an entity in a class with nested classes, you can use the `@NestedProjectedClass` annotation on those nested classes. [source,java] ---- diff --git a/extensions/panache/hibernate-orm-panache-common/runtime/src/main/java/io/quarkus/hibernate/orm/panache/common/NestedProjectedClass.java b/extensions/panache/hibernate-orm-panache-common/runtime/src/main/java/io/quarkus/hibernate/orm/panache/common/NestedProjectedClass.java index a797b44bc4173d..6963d3afa1d1bb 100644 --- a/extensions/panache/hibernate-orm-panache-common/runtime/src/main/java/io/quarkus/hibernate/orm/panache/common/NestedProjectedClass.java +++ b/extensions/panache/hibernate-orm-panache-common/runtime/src/main/java/io/quarkus/hibernate/orm/panache/common/NestedProjectedClass.java @@ -6,8 +6,7 @@ import java.lang.annotation.Target; /** - * Define a Class that is used for query projection, - * Identify nested object type that is projected. + * Define a class that is used for query projection as a nest inside the projected class. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff --git a/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/NestedProjectedClass.java b/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/NestedProjectedClass.java index f1917f2e3bad26..f57017b7e00fcf 100644 --- a/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/NestedProjectedClass.java +++ b/extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/NestedProjectedClass.java @@ -6,8 +6,7 @@ import java.lang.annotation.Target; /** - * Define a Class that is used for query projection, - * Identify nested object type that is projected. + * Define a class that is used for query projection as a nest inside the projected class. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff --git a/integration-tests/hibernate-orm-panache/src/main/java/io/quarkus/it/panache/PersonDTO.java b/integration-tests/hibernate-orm-panache/src/main/java/io/quarkus/it/panache/PersonDTO.java index 1cd1890b6de194..58f5c874c63c7a 100644 --- a/integration-tests/hibernate-orm-panache/src/main/java/io/quarkus/it/panache/PersonDTO.java +++ b/integration-tests/hibernate-orm-panache/src/main/java/io/quarkus/it/panache/PersonDTO.java @@ -8,19 +8,16 @@ public class PersonDTO extends PersonName { public final AddressDTO address; - @ProjectedFieldName("address") - public final AddressDTO address2; public final DescriptionDTO description; @ProjectedFieldName("description.size") public final Integer directHeight; - public PersonDTO(String uniqueName, String name, AddressDTO address, AddressDTO address2, DescriptionDTO description, + public PersonDTO(String uniqueName, String name, AddressDTO address, DescriptionDTO description, Integer directHeight) { super(uniqueName, name); this.address = address; - this.address2 = address2; this.description = description; this.directHeight = directHeight; } @@ -28,18 +25,12 @@ public PersonDTO(String uniqueName, String name, AddressDTO address, AddressDTO @NestedProjectedClass public static class AddressDTO implements Comparable { - // Simple filed with automatic mapping in constructor + // Simple field with automatic mapping in constructor public final String street; - @ProjectedFieldName("street") - public final String street2; - - private final String street3; - - public AddressDTO(String street, String street2, @ProjectedFieldName("street") String street3) { + public AddressDTO(String street) { this.street = street; - this.street2 = street2; - this.street3 = street3; + } @Override @@ -47,9 +38,6 @@ public int compareTo(AddressDTO address) { return street.compareTo(address.street); } - public String getStreet3() { - return street3; - } } @NestedProjectedClass @@ -59,27 +47,13 @@ public static class DescriptionDTO { @ProjectedFieldName("size") public final Integer height; - public final EmbeddedDescriptionDTO description2; - - public DescriptionDTO(Integer height, Integer weight, EmbeddedDescriptionDTO description2) { + public DescriptionDTO(Integer height, Integer weight) { this.height = height; - this.description2 = description2; this.description = "Height: " + height + ", weight: " + weight; } - public String getGeneratedDescription() { + public String getDescription() { return description; } } - - @NestedProjectedClass - public static class EmbeddedDescriptionDTO { - @ProjectedFieldName("embeddedDescription") - public final String value; - - public EmbeddedDescriptionDTO(String value) { - this.value = value; - } - - } } diff --git a/integration-tests/hibernate-orm-panache/src/main/java/io/quarkus/it/panache/PersonDescription.java b/integration-tests/hibernate-orm-panache/src/main/java/io/quarkus/it/panache/PersonDescription.java index 83883fde6e3ba2..1680db956dfba3 100644 --- a/integration-tests/hibernate-orm-panache/src/main/java/io/quarkus/it/panache/PersonDescription.java +++ b/integration-tests/hibernate-orm-panache/src/main/java/io/quarkus/it/panache/PersonDescription.java @@ -6,6 +6,4 @@ public class PersonDescription { public Integer size; public Integer weight; - public PersonDescriptionEmbedded description2; - } 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 093b636910fb5b..41f7f53e7efbf5 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 @@ -244,6 +244,7 @@ void testEnhancement27184DeleteDetached() { void testSimpleEntityProjection() { Person person = new Person(); person.name = "1"; + person.uniqueName = "1"; person.persist(); PersonName personName = Person.find(" name = ?1", "1") @@ -261,7 +262,6 @@ void testSimpleEntityProjection2() { person.name = "1"; person.uniqueName = "1"; person.persist(); - String personName = Person.find("select name from Person2 where name = ?1", "1") .project(String.class) .firstResult(); @@ -274,24 +274,21 @@ void testSimpleEntityProjection2() { void testNestedEntityProjection_WithQuery() { Person person = new Person(); person.name = "2"; + person.uniqueName = "2"; person.address = new Address("street 2"); person.persist(); - PersonDTO personNameAddress = Person.find( + PersonDTO personDTO = Person.find( "select uniqueName, name, " + - " new io.quarkus.it.panache.PersonDTO$AddressDTO( address.street, address.street, address.street)," + - " new io.quarkus.it.panache.PersonDTO$AddressDTO( address.street, address.street, address.street)," + - " new io.quarkus.it.panache.PersonDTO$DescriptionDTO(description.size, description.weight, " + - " new io.quarkus.it.panache.PersonDTO$EmbeddedDescriptionDTO(description.description2.embeddedDescription)" - + - ")," + + " new io.quarkus.it.panache.PersonDTO$AddressDTO(address.street)," + + " new io.quarkus.it.panache.PersonDTO$DescriptionDTO(description.size, description.weight)," + " description.size" + " from Person2 where name = ?1", "2") .project(PersonDTO.class) .firstResult(); person.delete(); - Assertions.assertEquals("2", personNameAddress.name); - Assertions.assertEquals("street 2", personNameAddress.address2.street); + Assertions.assertEquals("2", personDTO.name); + Assertions.assertEquals("street 2", personDTO.address.street); } @Test @@ -304,21 +301,16 @@ void testNestedEntityProjection() { person.description = new PersonDescription(); person.description.weight = 75; person.description.size = 170; - person.description.description2 = new PersonDescriptionEmbedded(); - person.description.description2.embeddedDescription = "embedded"; person.persist(); PersonDTO personDTO = Person.find(" name = ?1", "3") .project(PersonDTO.class) .firstResult(); person.delete(); Assertions.assertEquals("3", personDTO.name); - Assertions.assertEquals("street 3", personDTO.address2.street); - Assertions.assertEquals("street 3", personDTO.address2.street2); - Assertions.assertEquals("street 3", personDTO.address2.getStreet3()); + Assertions.assertEquals("street 3", personDTO.address.street); Assertions.assertEquals(170, personDTO.directHeight); Assertions.assertEquals(170, personDTO.description.height); - Assertions.assertEquals("Height: 170, weight: 75", personDTO.description.getGeneratedDescription()); - Assertions.assertEquals("embedded", personDTO.description.description2.value); + Assertions.assertEquals("Height: 170, weight: 75", personDTO.description.getDescription()); } @Test @@ -326,11 +318,11 @@ void testNestedEntityProjection() { void testDogDto2Projection() { Person hum = new Person(); hum.name = "hum"; + hum.uniqueName = "hum"; Dog kit = new Dog("kit", "bulldog"); hum.dogs.add(kit); kit.owner = hum; hum.persist(); - DogDto2 dogDto2 = Dog.find(" name = ?1", "kit") .project(DogDto2.class) .firstResult(); diff --git a/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/DogDto2.java b/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/DogDto.java similarity index 68% rename from integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/DogDto2.java rename to integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/DogDto.java index 81f863b2453aa8..594c600e25c054 100644 --- a/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/DogDto2.java +++ b/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/DogDto.java @@ -4,20 +4,20 @@ import io.quarkus.runtime.annotations.RegisterForReflection; @RegisterForReflection -public class DogDto2 { +public class DogDto { public String name; - public PersonDto2 owner; + public PersonDto owner; - public DogDto2(String name, PersonDto2 owner) { + public DogDto(String name, PersonDto owner) { this.name = name; this.owner = owner; } @NestedProjectedClass - public static class PersonDto2 { + public static class PersonDto { public String name; - public PersonDto2(String name) { + public PersonDto(String name) { this.name = name; } } diff --git a/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/Person.java b/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/Person.java index 1859fe7ef8ec45..2cb01a50cff072 100644 --- a/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/Person.java +++ b/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/Person.java @@ -5,7 +5,18 @@ import java.util.ArrayList; import java.util.List; -import jakarta.persistence.*; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.NamedQueries; +import jakarta.persistence.NamedQuery; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Transient; import jakarta.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.XmlTransient; @@ -36,11 +47,8 @@ }) @FilterDef(name = "Person.hasName", defaultCondition = "name = :name", parameters = @ParamDef(name = "name", type = String.class)) @FilterDef(name = "Person.isAlive", defaultCondition = "status = 'LIVING'") -@FilterDef(name = "Person.name.in", defaultCondition = "name in (:names)", parameters = { - @ParamDef(name = "names", type = String.class) }) @Filter(name = "Person.isAlive") @Filter(name = "Person.hasName") -@Filter(name = "Person.name.in") public class Person extends PanacheEntity { public String name; @@ -88,8 +96,4 @@ public void setSerialisationTrick(int serialisationTrick) { public static long methodWithPrimitiveParams(boolean b, byte bb, short s, int i, long l, float f, double d, char c) { return 0; } - - public static void voidMethod() { - throw new RuntimeException("void"); - } } diff --git a/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/PersonDTO.java b/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/PersonDTO.java index b4fdcae5bb82ea..79aa802a9e5a20 100644 --- a/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/PersonDTO.java +++ b/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/PersonDTO.java @@ -6,21 +6,17 @@ @RegisterForReflection public class PersonDTO extends PersonName { - public final AddressDTO address; - @ProjectedFieldName("address") - public final AddressDTO address2; public final DescriptionDTO description; @ProjectedFieldName("description.size") public final Integer directHeight; - public PersonDTO(String uniqueName, String name, AddressDTO address, AddressDTO address2, DescriptionDTO description, + public PersonDTO(String uniqueName, String name, AddressDTO address, DescriptionDTO description, Integer directHeight) { super(uniqueName, name); this.address = address; - this.address2 = address2; this.description = description; this.directHeight = directHeight; } @@ -28,18 +24,10 @@ public PersonDTO(String uniqueName, String name, AddressDTO address, AddressDTO @NestedProjectedClass public static class AddressDTO implements Comparable { - // Simple field with automatic mapping in constructor public final String street; - @ProjectedFieldName("street") - public final String street2; - - private final String street3; - - public AddressDTO(String street, String street2, @ProjectedFieldName("street") String street3) { + public AddressDTO(String street) { this.street = street; - this.street2 = street2; - this.street3 = street3; } @Override @@ -47,9 +35,6 @@ public int compareTo(AddressDTO address) { return street.compareTo(address.street); } - public String getStreet3() { - return street3; - } } @NestedProjectedClass @@ -59,11 +44,8 @@ public static class DescriptionDTO { @ProjectedFieldName("size") public final Integer height; - public final EmbeddedDescriptionDTO description2; - - public DescriptionDTO(Integer height, Integer weight, EmbeddedDescriptionDTO description2) { + public DescriptionDTO(Integer height, Integer weight) { this.height = height; - this.description2 = description2; this.description = "Height: " + height + ", weight: " + weight; } @@ -71,15 +53,4 @@ public String getGeneratedDescription() { return description; } } - - @NestedProjectedClass - public static class EmbeddedDescriptionDTO { - @ProjectedFieldName("embeddedDescription") - public final String value; - - public EmbeddedDescriptionDTO(String value) { - this.value = value; - } - - } } diff --git a/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/PersonDescription.java b/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/PersonDescription.java index a4becb83e043ea..31daac1427033a 100644 --- a/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/PersonDescription.java +++ b/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/PersonDescription.java @@ -6,6 +6,4 @@ public class PersonDescription { public Integer size; public Integer weight; - public PersonDescriptionEmbedded description2; - } diff --git a/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/PersonDescriptionEmbedded.java b/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/PersonDescriptionEmbedded.java deleted file mode 100644 index 2b2679d2817fc0..00000000000000 --- a/integration-tests/hibernate-reactive-panache/src/main/java/io/quarkus/it/panache/reactive/PersonDescriptionEmbedded.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.quarkus.it.panache.reactive; - -import jakarta.persistence.Embeddable; - -@Embeddable -public class PersonDescriptionEmbedded { - public String embeddedDescription; -} diff --git a/integration-tests/hibernate-reactive-panache/src/test/java/io/quarkus/it/panache/reactive/PanacheFunctionalityTest.java b/integration-tests/hibernate-reactive-panache/src/test/java/io/quarkus/it/panache/reactive/PanacheFunctionalityTest.java index a1241486892828..777c27c2e79073 100644 --- a/integration-tests/hibernate-reactive-panache/src/test/java/io/quarkus/it/panache/reactive/PanacheFunctionalityTest.java +++ b/integration-tests/hibernate-reactive-panache/src/test/java/io/quarkus/it/panache/reactive/PanacheFunctionalityTest.java @@ -332,8 +332,6 @@ void testNestedEntityProjection(UniAsserter asserter) { person.description = new PersonDescription(); person.description.weight = 75; person.description.size = 170; - person.description.description2 = new PersonDescriptionEmbedded(); - person.description.description2.embeddedDescription = "embedded"; asserter.execute(() -> person.persist()); asserter.assertThat( () -> Person.find(" name = ?1", "3") @@ -341,13 +339,10 @@ void testNestedEntityProjection(UniAsserter asserter) { .firstResult(), personDTO -> { Assertions.assertEquals("3", personDTO.name); - Assertions.assertEquals("street 3", personDTO.address2.street); - Assertions.assertEquals("street 3", personDTO.address2.street2); - Assertions.assertEquals("street 3", personDTO.address2.getStreet3()); + Assertions.assertEquals("street 3", personDTO.address.street); Assertions.assertEquals(170, personDTO.directHeight); Assertions.assertEquals(170, personDTO.description.height); Assertions.assertEquals("Height: 170, weight: 75", personDTO.description.getGeneratedDescription()); - Assertions.assertEquals("embedded", personDTO.description.description2.value); }); asserter.execute(() -> person.delete()); } @@ -357,18 +352,19 @@ void testNestedEntityProjection(UniAsserter asserter) { void testDogDto2Projection(UniAsserter asserter) { Person hum = new Person(); hum.name = "hum"; + hum.uniqueName = "hum"; Dog kit = new Dog("kit", "bulldog"); hum.dogs.add(kit); kit.owner = hum; asserter.execute(() -> hum.persist()); asserter.assertThat( () -> Dog.find(" name = ?1", "kit") - .project(DogDto2.class) + .project(DogDto.class) .firstResult(), - dogDto2 -> { - Assertions.assertNotNull(dogDto2); - Assertions.assertEquals("kit", dogDto2.name); - Assertions.assertEquals("hum", dogDto2.owner.name); + dogDto -> { + Assertions.assertNotNull(dogDto); + Assertions.assertEquals("kit", dogDto.name); + Assertions.assertEquals("hum", dogDto.owner.name); }); asserter.execute(() -> hum.delete()); }