Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add simple test/example with DogDto2
Rename annotation
Add documentation
  • Loading branch information
humcqc committed Jan 31, 2024
1 parent 11c3c36 commit ab54873
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 18 deletions.
30 changes: 30 additions & 0 deletions docs/src/main/asciidoc/hibernate-orm-panache.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,36 @@ PanacheQuery<DogDto> 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.

[source,java]
----
@RegisterForReflection
public class DogDto2 {
public String name;
public PersonDto2 owner;
public DogDto2(String name, PersonDto2 owner) {
this.name = name;
this.owner = owner;
}
@NestedProjectedClass // <1>
public static class PersonDto2 {
public String name;
public PersonDto2(String name) {
this.name = name;
}
}
}
PanacheQuery<DogDto2> query = Dog.findAll().project(DogDto2.class);
----

<1> This annotation can be used when you want to project `@Embedded` entity or `@ManyToOne`, `@OneToOne` relation.
It does not support `@OneToMany` or `@ManyToMany` relation.

It is also possible to specify a HQL query with a select clause. In this case, the projection class must have a constructor
matching the values returned by the select clause:

Expand Down
31 changes: 31 additions & 0 deletions docs/src/main/asciidoc/hibernate-reactive-panache.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,37 @@ PanacheQuery<DogDto> 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.

[source,java]
----
@RegisterForReflection
public class DogDto2 {
public String name;
public PersonDto2 owner;
public DogDto2(String name, PersonDto2 owner) {
this.name = name;
this.owner = owner;
}
@NestedProjectedClass // <1>
public static class PersonDto2 {
public String name;
public PersonDto2(String name) {
this.name = name;
}
}
}
PanacheQuery<DogDto2> query = Dog.findAll().project(DogDto2.class);
----

<1> This annotation can be used when you want to project `@Embedded` entity or `@ManyToOne`, `@OneToOne` relation.
It does not support `@OneToMany` or `@ManyToMany` relation.

It is also possible to specify a HQL query with a select clause. In this case, the projection class must have a constructor
matching the values returned by the select clause:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ProjectedClass {
public @interface NestedProjectedClass {
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import org.hibernate.Filter;
import org.hibernate.Session;

import io.quarkus.hibernate.orm.panache.common.ProjectedClass;
import io.quarkus.hibernate.orm.panache.common.NestedProjectedClass;
import io.quarkus.hibernate.orm.panache.common.ProjectedFieldName;
import io.quarkus.panache.common.Page;
import io.quarkus.panache.common.Range;
Expand Down Expand Up @@ -172,7 +172,7 @@ private String getParameterName(Class<?> parentType, String parentParameter, Par
// For nested classes, add parent parameter in parameterName
parameterName = (parentParameter == null) ? parameterName : parentParameter.concat(".").concat(parameterName);
// Test if the parameter is a nested Class that should be projected too.
if (parameter.getType().isAnnotationPresent(ProjectedClass.class)) {
if (parameter.getType().isAnnotationPresent(NestedProjectedClass.class)) {
Class<?> nestedType = parameter.getType();
return getParameterFromClass(nestedType, parameterName).toString();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ProjectedClass {
public @interface NestedProjectedClass {
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import org.hibernate.Filter;
import org.hibernate.reactive.mutiny.Mutiny;

import io.quarkus.hibernate.reactive.panache.common.ProjectedClass;
import io.quarkus.hibernate.reactive.panache.common.NestedProjectedClass;
import io.quarkus.hibernate.reactive.panache.common.ProjectedFieldName;
import io.quarkus.panache.common.Page;
import io.quarkus.panache.common.Range;
Expand Down Expand Up @@ -162,7 +162,7 @@ private String getParameterName(Class<?> parentType, String parentParameter, Par
// For nested classes, add parent parameter in parameterName
parameterName = (parentParameter == null) ? parameterName : parentParameter.concat(".").concat(parameterName);
// Test if the parameter is a nested Class that should be projected too.
if (parameter.getType().isAnnotationPresent(ProjectedClass.class)) {
if (parameter.getType().isAnnotationPresent(NestedProjectedClass.class)) {
Class<?> nestedType = parameter.getType();
return getParameterFromClass(nestedType, parameterName).toString();
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.it.panache;

import io.quarkus.hibernate.orm.panache.common.NestedProjectedClass;
import io.quarkus.runtime.annotations.RegisterForReflection;

@RegisterForReflection
public class DogDto2 {
public String name;
public PersonDto2 owner;

public DogDto2(String name, PersonDto2 owner) {
this.name = name;
this.owner = owner;
}

@NestedProjectedClass
public static class PersonDto2 {
public String name;

public PersonDto2(String name) {
this.name = name;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package io.quarkus.it.panache;

import io.quarkus.hibernate.orm.panache.common.ProjectedClass;
import io.quarkus.hibernate.orm.panache.common.NestedProjectedClass;
import io.quarkus.hibernate.orm.panache.common.ProjectedFieldName;
import io.quarkus.runtime.annotations.RegisterForReflection;

@RegisterForReflection
@ProjectedClass
public class PersonDTO extends PersonName {

public final AddressDTO address;
Expand All @@ -26,7 +25,7 @@ public PersonDTO(String uniqueName, String name, AddressDTO address, AddressDTO
this.directHeight = directHeight;
}

@ProjectedClass
@NestedProjectedClass
public static class AddressDTO implements Comparable<AddressDTO> {

// Simple filed with automatic mapping in constructor
Expand All @@ -53,7 +52,7 @@ public String getStreet3() {
}
}

@ProjectedClass
@NestedProjectedClass
public static class DescriptionDTO {
private final String description;

Expand All @@ -78,7 +77,7 @@ public String getGeneratedDescription() {
}
}

@ProjectedClass
@NestedProjectedClass
public static class EmbeddedDescriptionDTO {
@ProjectedFieldName("embeddedDescription")
public final String value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,22 @@ void testNestedEntityProjection() {
Assertions.assertEquals("Height: 170, weight: 75", personDTO.description.getGeneratedDescription());
Assertions.assertEquals("embedded", personDTO.description.description2.value);
}

@Test
@Transactional
void testDogDto2Projection() {
Person hum = new Person();
hum.name = "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();
hum.delete();
Assertions.assertEquals("kit", dogDto2.name);
Assertions.assertEquals("hum", dogDto2.owner.name);
}
}
4 changes: 2 additions & 2 deletions integration-tests/hibernate-reactive-panache/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,13 @@
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
<skip>false</skip>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skip>true</skip>
<skip>false</skip>
</configuration>
</plugin>
<plugin>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.it.panache.reactive;

import io.quarkus.hibernate.reactive.panache.common.NestedProjectedClass;
import io.quarkus.runtime.annotations.RegisterForReflection;

@RegisterForReflection
public class DogDto2 {
public String name;
public PersonDto2 owner;

public DogDto2(String name, PersonDto2 owner) {
this.name = name;
this.owner = owner;
}

@NestedProjectedClass
public static class PersonDto2 {
public String name;

public PersonDto2(String name) {
this.name = name;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package io.quarkus.it.panache.reactive;

import io.quarkus.hibernate.reactive.panache.common.ProjectedClass;
import io.quarkus.hibernate.reactive.panache.common.NestedProjectedClass;
import io.quarkus.hibernate.reactive.panache.common.ProjectedFieldName;
import io.quarkus.runtime.annotations.RegisterForReflection;

@RegisterForReflection
@ProjectedClass
public class PersonDTO extends PersonName {

public final AddressDTO address;
Expand All @@ -26,7 +25,7 @@ public PersonDTO(String uniqueName, String name, AddressDTO address, AddressDTO
this.directHeight = directHeight;
}

@ProjectedClass
@NestedProjectedClass
public static class AddressDTO implements Comparable<AddressDTO> {

// Simple field with automatic mapping in constructor
Expand All @@ -53,7 +52,7 @@ public String getStreet3() {
}
}

@ProjectedClass
@NestedProjectedClass
public static class DescriptionDTO {
private final String description;

Expand All @@ -78,7 +77,7 @@ public String getGeneratedDescription() {
}
}

@ProjectedClass
@NestedProjectedClass
public static class EmbeddedDescriptionDTO {
@ProjectedFieldName("embeddedDescription")
public final String value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,4 +349,24 @@ void testNestedEntityProjection(UniAsserter asserter) {
});
asserter.execute(() -> person.delete());
}

@Test
@TestReactiveTransaction
void testDogDto2Projection(UniAsserter asserter) {
Person hum = new Person();
hum.name = "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)
.firstResult(),
dogDto2 -> {
Assertions.assertEquals("kit", dogDto2.name);
Assertions.assertEquals("hum", dogDto2.owner.name);
});
asserter.execute(() -> hum.delete());
}
}

0 comments on commit ab54873

Please sign in to comment.