Skip to content

Commit 8cd1388

Browse files
committed
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.
1 parent dccc580 commit 8cd1388

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,12 @@ protected CriteriaQuery<? extends Object> complete(@Nullable Predicate predicate
176176
selections.add(toExpressionRecursively(root, path, true).alias(property));
177177
}
178178

179-
query = query.multiselect(selections);
179+
Class<?> typeToRead = returnedType.getTypeToRead();
180+
181+
query = typeToRead.isInterface()
182+
? query.multiselect(selections)
183+
: query.select((Selection) builder.construct(typeToRead,
184+
selections.toArray(new Selection[0])));
180185

181186
} else if (tree.isExistsProjection()) {
182187

src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java

+8
Original file line numberDiff line numberDiff line change
@@ -2599,6 +2599,14 @@ void findByElementCollectionInAttributeIgnoreCaseWithNulls() {
25992599
assertThat(result).containsOnly(firstUser);
26002600
}
26012601

2602+
@Test // #2363
2603+
void readsDtoProjections() {
2604+
2605+
flushTestUsers();
2606+
2607+
assertThat(repository.findAllDtoProjectedBy()).hasSize(4);
2608+
}
2609+
26022610
private Page<User> executeSpecWithSort(Sort sort) {
26032611

26042612
flushTestUsers();

src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java

+3
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,9 @@ Page<User> findAllOrderedBySpecialNameMultipleParams(@Param("name") String name,
611611
// DATAJPA-1303
612612
Page<User> findByAttributesIgnoreCaseIn(Pageable pageable, String... attributes);
613613

614+
// #2363
615+
List<NameOnlyDto> findAllDtoProjectedBy();
616+
614617
interface RolesAndFirstname {
615618

616619
String getFirstname();

0 commit comments

Comments
 (0)