Skip to content

Commit 5413922

Browse files
authored
Merge pull request quarkusio#52783 from geoand/quarkusio#34350-take2
Handle projections with generic types
2 parents 0a12f18 + 13b14a4 commit 5413922

File tree

7 files changed

+144
-2
lines changed

7 files changed

+144
-2
lines changed

extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/AbstractMethodsAdder.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ protected Type verifyQueryResultType(Type t, IndexView index) {
301301
return verifyQueryResultType(t.asArrayType().constituent(), index);
302302
} else if (t.kind() == Type.Kind.PARAMETERIZED_TYPE) {
303303
final List<Type> types = t.asParameterizedType().arguments();
304-
if (types.size() == 1) {
304+
if (types.size() == 1 && isKnownContainerType(t.name())) {
305305
return verifyQueryResultType(types.get(0), index);
306306
} else {
307307
for (Type type : types) {
@@ -319,6 +319,17 @@ protected Type verifyQueryResultType(Type t, IndexView index) {
319319
return t;
320320
}
321321

322+
private static boolean isKnownContainerType(DotName name) {
323+
return DotNames.LIST.equals(name)
324+
|| DotNames.COLLECTION.equals(name)
325+
|| DotNames.SET.equals(name)
326+
|| DotNames.OPTIONAL.equals(name)
327+
|| DotNames.STREAM.equals(name)
328+
|| DotNames.ITERATOR.equals(name)
329+
|| DotNames.SPRING_DATA_PAGE.equals(name)
330+
|| DotNames.SPRING_DATA_SLICE.equals(name);
331+
}
332+
322333
protected DotName createSimpleInterfaceImpl(DotName ifaceName, DotName entityName) {
323334
String fullName = ifaceName.toString();
324335

extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/DerivedMethodsAdder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ private Type extractResultType(ClassInfo repositoryClassInfo, MethodInfo method)
300300

301301
int matchingIndex = -1;
302302
for (int i = 0; i < interfaceTypeVariables.size(); i++) {
303-
if (interfaceTypeVariables.get(i).equals(resultTypeVariable)) {
303+
if (interfaceTypeVariables.get(i).identifier().equals(resultTypeVariable.identifier())) {
304304
matchingIndex = i;
305305
break;
306306
}

integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/generics/FatherBase.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,24 @@ public class FatherBase<T extends ChildBase> {
1414
float test;
1515
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
1616
private List<T> children;
17+
18+
public String getName() {
19+
return name;
20+
}
21+
22+
public String getDetail() {
23+
return detail;
24+
}
25+
26+
public int getAge() {
27+
return age;
28+
}
29+
30+
public float getTest() {
31+
return test;
32+
}
33+
34+
public List<T> getChildren() {
35+
return children;
36+
}
1737
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package io.quarkus.it.spring.data.jpa.generics;
2+
3+
import java.util.List;
4+
import java.util.Optional;
5+
6+
import org.springframework.data.jpa.repository.JpaRepository;
7+
import org.springframework.data.repository.NoRepositoryBean;
8+
9+
@NoRepositoryBean
10+
public interface MultiTypeParamBaseRepository<T extends FatherBase<C>, C extends ChildBase> extends JpaRepository<T, Long> {
11+
List<T> findAllTestById(Long id);
12+
13+
Optional<SmallParent> findSomethingByIdAndName(Long id, String name);
14+
15+
GenericParent<C> findChildrenById(Long id);
16+
17+
interface GenericParent<T extends ChildBase> {
18+
List<T> getChildren();
19+
}
20+
21+
interface SmallParent {
22+
int getAge();
23+
24+
float getTest();
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package io.quarkus.it.spring.data.jpa.generics;
2+
3+
public interface MultiTypeParamFatherRepository extends MultiTypeParamBaseRepository<Father, Child> {
4+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package io.quarkus.it.spring.data.jpa.generics;
2+
3+
import java.util.List;
4+
import java.util.Optional;
5+
6+
import jakarta.enterprise.context.ApplicationScoped;
7+
import jakarta.ws.rs.GET;
8+
import jakarta.ws.rs.Path;
9+
import jakarta.ws.rs.PathParam;
10+
import jakarta.ws.rs.Produces;
11+
import jakarta.ws.rs.core.MediaType;
12+
13+
@Path("/rest/multi-type-param-fathers")
14+
@ApplicationScoped
15+
public class MultiTypeParamResource {
16+
private final MultiTypeParamFatherRepository repository;
17+
18+
public MultiTypeParamResource(MultiTypeParamFatherRepository repository) {
19+
this.repository = repository;
20+
}
21+
22+
@GET
23+
@Path("/findAllTestById/{id}")
24+
@Produces(MediaType.TEXT_PLAIN)
25+
public int findAllTestById(@PathParam("id") Long id) {
26+
List<Father> fathers = repository.findAllTestById(id);
27+
return fathers.size();
28+
}
29+
30+
@GET
31+
@Path("/findSomethingByIdAndName/{id}/{name}")
32+
@Produces(MediaType.TEXT_PLAIN)
33+
public String findSomethingByIdAndName(@PathParam("id") Long id, @PathParam("name") String name) {
34+
Optional<MultiTypeParamBaseRepository.SmallParent> result = repository.findSomethingByIdAndName(id, name);
35+
return result.map(p -> p.getAge() + ":" + p.getTest()).orElse("empty");
36+
}
37+
38+
@GET
39+
@Path("/findChildrenById/{id}")
40+
@Produces(MediaType.TEXT_PLAIN)
41+
public int findChildrenById(@PathParam("id") Long id) {
42+
MultiTypeParamBaseRepository.GenericParent<Child> result = repository.findChildrenById(id);
43+
return result.getChildren().size();
44+
}
45+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package io.quarkus.it.spring.data.jpa.generics;
2+
3+
import static io.restassured.RestAssured.given;
4+
import static org.hamcrest.CoreMatchers.containsString;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
import io.quarkus.test.junit.QuarkusTest;
9+
10+
@QuarkusTest
11+
public class MultiTypeParamResourceTest {
12+
13+
@Test
14+
public void shouldFindAllTestById() {
15+
given()
16+
.when().get("/rest/multi-type-param-fathers/findAllTestById/1")
17+
.then()
18+
.statusCode(200).body(containsString("1"));
19+
}
20+
21+
@Test
22+
public void shouldFindSomethingByIdAndName() {
23+
given()
24+
.when().get("/rest/multi-type-param-fathers/findSomethingByIdAndName/1/John Doe")
25+
.then()
26+
.statusCode(200).body(containsString("40:75.5"));
27+
}
28+
29+
@Test
30+
public void shouldFindChildrenById() {
31+
given()
32+
.when().get("/rest/multi-type-param-fathers/findChildrenById/1")
33+
.then()
34+
.statusCode(200).body(containsString("3"));
35+
}
36+
}

0 commit comments

Comments
 (0)