Skip to content

Commit

Permalink
Fix Native Query projections mapping to DTOs.
Browse files Browse the repository at this point in the history
We now provide the target type to createNativeQuery(…) if we detect that a native query result type is a projection and not an interface.

Closes #2757
  • Loading branch information
mp911de committed Dec 3, 2024
1 parent 229db64 commit b0f8c51
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,15 @@ private Class<?> getTypeToQueryFor(ReturnedType returnedType) {
return result;
}

return returnedType.isProjecting() && !getMetamodel().isJpaManaged(returnedType.getReturnedType()) //
? Tuple.class
: result;
if (returnedType.isProjecting()) {

if (returnedType.getReturnedType().isInterface()) {
return Tuple.class;
}

return returnedType.getReturnedType();
}

return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import org.springframework.data.jpa.domain.sample.Role;
import org.springframework.data.jpa.domain.sample.SpecialUser;
import org.springframework.data.jpa.domain.sample.User;
import org.springframework.data.jpa.repository.sample.NameOnlyRecord;
import org.springframework.data.jpa.repository.sample.SampleEvaluationContextExtension.SampleSecurityContextHolder;
import org.springframework.data.jpa.repository.sample.UserRepository;
import org.springframework.data.jpa.repository.sample.UserRepository.NameOnly;
Expand Down Expand Up @@ -2979,6 +2980,19 @@ void supportsInterfaceProjectionsWithNativeQueries() {
assertThat(result.getLastname()).isEqualTo(user.getLastname());
}

@Test // GH-2757
void supportsRecordsWithNativeQueries() {

flushTestUsers();

User user = repository.findAll().get(0);

NameOnlyRecord result = repository.findRecordProjectionByNativeQuery(user.getId());

assertThat(result.firstname()).isEqualTo(user.getFirstname());
assertThat(result.lastname()).isEqualTo(user.getLastname());
}

@Test // DATAJPA-1248
void supportsProjectionsWithNativeQueriesAndCamelCaseProperty() {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright 2018-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jpa.repository.sample;

public record NameOnlyRecord(String firstname, String lastname) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,9 @@ List<User> findUsersByFirstnameForSpELExpressionWithParameterIndexOnlyWithEntity
@Query(value = "SELECT firstname, lastname FROM SD_User WHERE id = ?1", nativeQuery = true)
NameOnly findByNativeQuery(Integer id);

@NativeQuery("SELECT firstname, lastname FROM SD_User WHERE id = ?1")
NameOnlyRecord findRecordProjectionByNativeQuery(Integer id);

// GH-3155
@NativeQuery(value = "SELECT emailaddress, secondary_email_address FROM SD_User WHERE id = ?1",
sqlResultSetMapping = "emailDto")
Expand Down

0 comments on commit b0f8c51

Please # to comment.