From a1faffe4afa7a05715ea98dc7163fcf8e0affef2 Mon Sep 17 00:00:00 2001 From: Oliver Drotbohm Date: Tue, 25 Jan 2022 09:15:52 +0100 Subject: [PATCH] Fix potential NullPointerException in JpaQueryCreator. With the commit for GH-2363, we introduced an unguarded call to ReturnedType.getTypeToRead(), which could return null under certain conditions. Unfortunately Spring Data JPA dod not contain a test case that triggered that scenario. This commit switches to ReturnedType.getReturnedType() which is non-nullable and lets us inspect the calls results for interfaces, which we need to create the JPA query properly. Fixes GH-2408 --- .../data/jpa/repository/query/JpaQueryCreator.java | 2 +- .../data/jpa/repository/UserRepositoryTests.java | 8 ++++++++ .../data/jpa/repository/sample/UserRepository.java | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java index 7584cd6994..6777a4e8b9 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java @@ -164,7 +164,7 @@ protected CriteriaQuery complete(@Nullable Predicate predicate selections.add(toExpressionRecursively(root, path, true).alias(property)); } - Class typeToRead = returnedType.getTypeToRead(); + Class typeToRead = returnedType.getReturnedType(); query = typeToRead.isInterface() ? query.multiselect(selections) diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java index e481be31fa..a07ea34028 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java @@ -2630,6 +2630,14 @@ void readsDtoProjections() { assertThat(repository.findAllDtoProjectedBy()).hasSize(4); } + @Test // GH-2408, GH-2363 + void readsDerivedInterfaceProjections() { + + flushTestUsers(); + + assertThat(repository.findAllInterfaceProjectedBy()).hasSize(4); + } + private Page executeSpecWithSort(Sort sort) { flushTestUsers(); diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java index 32b0b36767..6570a5ea87 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java @@ -614,6 +614,9 @@ Page findAllOrderedBySpecialNameMultipleParams(@Param("name") String name, // #2363 List findAllDtoProjectedBy(); + // GH-2408 + List findAllInterfaceProjectedBy(); + interface RolesAndFirstname { String getFirstname();