Skip to content

Commit 806e02b

Browse files
committed
Adopt to changed Hibernate behavior returning domain types using tuple queries.
We now allow using the domain type when it is returned from a tuple query. This allows projections if the return value is not a Map. Closes #2815
1 parent 884a589 commit 806e02b

File tree

3 files changed

+30
-5
lines changed

3 files changed

+30
-5
lines changed

spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,18 +314,17 @@ public TupleConverter(ReturnedType type) {
314314
@Override
315315
public Object convert(Object source) {
316316

317-
if (!(source instanceof Tuple)) {
317+
if (!(source instanceof Tuple tuple)) {
318318
return source;
319319
}
320320

321-
Tuple tuple = (Tuple) source;
322321
List<TupleElement<?>> elements = tuple.getElements();
323322

324323
if (elements.size() == 1) {
325324

326325
Object value = tuple.get(elements.get(0));
327326

328-
if (type.isInstance(value) || value == null) {
327+
if (type.getDomainType().isInstance(value) || type.isInstance(value) || value == null) {
329328
return value;
330329
}
331330
}

spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
import org.springframework.data.jpa.provider.PersistenceProvider;
4040
import org.springframework.data.jpa.repository.sample.RoleRepository;
4141
import org.springframework.data.jpa.repository.sample.UserRepository;
42+
import org.springframework.data.jpa.repository.sample.UserRepository.IdOnly;
43+
import org.springframework.data.jpa.repository.sample.UserRepository.RolesAndFirstname;
4244
import org.springframework.data.repository.query.QueryLookupStrategy;
4345
import org.springframework.test.context.ContextConfiguration;
4446
import org.springframework.test.context.junit.jupiter.SpringExtension;
@@ -276,11 +278,28 @@ void translatesNotContainsToNotMemberOf() {
276278
.containsExactlyInAnyOrder(dave, oliver);
277279
}
278280

279-
@Test // DATAJPA-974
281+
@Test // DATAJPA-974, GH-2815
280282
void executesQueryWithProjectionContainingReferenceToPluralAttribute() {
281283

282-
assertThat(userRepository.findRolesAndFirstnameBy()) //
284+
List<RolesAndFirstname> rolesAndFirstnameBy = userRepository.findRolesAndFirstnameBy();
285+
286+
assertThat(rolesAndFirstnameBy)
283287
.isNotNull();
288+
289+
for (RolesAndFirstname rolesAndFirstname : rolesAndFirstnameBy) {
290+
assertThat(rolesAndFirstname.getFirstname()).isNotNull();
291+
assertThat(rolesAndFirstname.getRoles()).isNotNull();
292+
}
293+
}
294+
295+
@Test // GH-2815
296+
void executesQueryWithProjectionThroughStringQuery() {
297+
298+
List<IdOnly> ids = userRepository.findIdOnly();
299+
300+
assertThat(ids).isNotNull();
301+
302+
assertThat(ids).extracting(IdOnly::getId).doesNotContainNull();
284303
}
285304

286305
@Test // DATAJPA-1023, DATACMNS-959

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,9 @@ List<User> findUsersByFirstnameForSpELExpressionWithParameterIndexOnlyWithEntity
551551

552552
List<RolesAndFirstname> findRolesAndFirstnameBy();
553553

554+
@Query(value = "FROM User u")
555+
List<IdOnly> findIdOnly();
556+
554557
// DATAJPA-1172
555558
@Query("select u from User u where u.age = :age")
556559
List<User> findByStringAge(@Param("age") String age);
@@ -721,4 +724,8 @@ interface NameOnly {
721724
interface EmailOnly {
722725
String getEmailAddress();
723726
}
727+
728+
interface IdOnly {
729+
int getId();
730+
}
724731
}

0 commit comments

Comments
 (0)