From 5f3b4e2155d2907c6c46b7c54adcda439ec847a7 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Wed, 24 Nov 2021 19:19:07 +0100 Subject: [PATCH] Add support for DTO projections on derived query methods. In case a derived query uses a DTO, we now create a select clause that uses a constructor expression for the DTO type. This wasn't supported before and expexted either an interface-based projection or an explicit query using a constructor expression. Fixes #2363. --- .../data/jpa/repository/query/JpaQueryCreator.java | 7 ++++++- .../data/jpa/repository/UserRepositoryTests.java | 8 ++++++++ .../data/jpa/repository/sample/UserRepository.java | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java index 825d8a341..3eb0762ee 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java @@ -176,7 +176,12 @@ public class JpaQueryCreator extends AbstractQueryCreator typeToRead = returnedType.getTypeToRead(); + + query = typeToRead.isInterface() + ? query.multiselect(selections) + : query.select((Selection) builder.construct(typeToRead, + selections.toArray(new Selection[0]))); } else if (tree.isExistsProjection()) { diff --git a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java index 623bb41fa..c2f7c4b52 100644 --- a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java @@ -2599,6 +2599,14 @@ public class UserRepositoryTests { assertThat(result).containsOnly(firstUser); } + @Test // #2363 + void readsDtoProjections() { + + flushTestUsers(); + + assertThat(repository.findAllDtoProjectedBy()).hasSize(4); + } + private Page executeSpecWithSort(Sort sort) { flushTestUsers(); diff --git a/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java b/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java index ab03b7967..721123ca1 100644 --- a/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java +++ b/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java @@ -611,6 +611,9 @@ public interface UserRepository // DATAJPA-1303 Page findByAttributesIgnoreCaseIn(Pageable pageable, String... attributes); + // #2363 + List findAllDtoProjectedBy(); + interface RolesAndFirstname { String getFirstname();