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.
This commit is contained in:
Oliver Drotbohm
2021-11-24 19:19:07 +01:00
committed by Jens Schauder
parent eaeec5d66c
commit 5f3b4e2155
3 changed files with 17 additions and 1 deletions

View File

@@ -176,7 +176,12 @@ public class JpaQueryCreator extends AbstractQueryCreator<CriteriaQuery<? extend
selections.add(toExpressionRecursively(root, path, true).alias(property));
}
query = query.multiselect(selections);
Class<?> typeToRead = returnedType.getTypeToRead();
query = typeToRead.isInterface()
? query.multiselect(selections)
: query.select((Selection) builder.construct(typeToRead,
selections.toArray(new Selection[0])));
} else if (tree.isExistsProjection()) {

View File

@@ -2599,6 +2599,14 @@ public class UserRepositoryTests {
assertThat(result).containsOnly(firstUser);
}
@Test // #2363
void readsDtoProjections() {
flushTestUsers();
assertThat(repository.findAllDtoProjectedBy()).hasSize(4);
}
private Page<User> executeSpecWithSort(Sort sort) {
flushTestUsers();

View File

@@ -611,6 +611,9 @@ public interface UserRepository
// DATAJPA-1303
Page<User> findByAttributesIgnoreCaseIn(Pageable pageable, String... attributes);
// #2363
List<NameOnlyDto> findAllDtoProjectedBy();
interface RolesAndFirstname {
String getFirstname();