Read domain type when returning an implemented interface from repository query methods.

We now read the domain type instead of trying to materialize an interface if the type returned from the query method is implemented by the domain object handled by the repository.

Closes #519
This commit is contained in:
Mark Paluch
2021-01-08 11:03:55 +01:00
parent cecad1c9cf
commit c745165366
3 changed files with 21 additions and 1 deletions

View File

@@ -129,6 +129,10 @@ public abstract class AbstractR2dbcQuery implements RepositoryQuery {
ReturnedType returnedType = resultProcessor.getReturnedType();
if (returnedType.getReturnedType().isAssignableFrom(returnedType.getDomainType())) {
return returnedType.getDomainType();
}
return returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType();
}

View File

@@ -394,11 +394,16 @@ public abstract class AbstractR2dbcRepositoryIntegrationTests extends R2dbcInteg
Mono<Boolean> existsByName(String name);
}
public interface Buildable {
String getName();
}
@Getter
@Setter
@Table("legoset")
@NoArgsConstructor
public static class LegoSet extends Lego {
public static class LegoSet extends Lego implements Buildable {
String name;
Integer manual;

View File

@@ -142,8 +142,19 @@ public class H2R2dbcRepositoryIntegrationTests extends AbstractR2dbcRepositoryIn
}).verifyComplete();
}
@Test // gh-519
public void shouldReturnEntityThroughInterface() {
shouldInsertNewItems();
repository.findByName("SCHAUFELRADBAGGER").map(Buildable::getName).as(StepVerifier::create)
.expectNext("SCHAUFELRADBAGGER").verifyComplete();
}
interface H2LegoSetRepository extends LegoSetRepository {
Mono<Buildable> findByName(String name);
@Query("SELECT MAX(manual) FROM legoset WHERE name = :name")
Mono<Integer> findMax(String name);