Skip to content

Projections doesn't work using data-repositories #475

Closed
@alesikov

Description

@alesikov

Hello,
Unfortunately any kind of projections doesn't work with data-repositories. It's probably caused by

return returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType();
which could be probably solved by the following
return returnedType.isProjecting() ? returnedType.getReturnedType() : returnedType.getDomainType();

The above was tested locally and it worked, please kindly check.

Activity

mp911de

mp911de commented on Oct 6, 2020

@mp911de
Member

Can you provide a test case that shows that projections are broken? Our integration tests for projections pass so it would be good to know in which case projections don't work.

alesikov

alesikov commented on Oct 6, 2020

@alesikov
Author

My bad, forgot to mention that the issue is related to @Query-annotated methods which produce class-based projections.
Apparently the tests don't cover the scenario when projection has different field names than the entity
Managed to reproduce the same using integration tests you mentioned previously, the proposed fix still works. Please try testing against the following:

// Projection
@Value
static class NamedDTO {
    String doesntBelongToEntity;
}

// Repository method
@Query("SELECT name as doesnt_belong_to_entity FROM legoset")
Flux<NamedDTO> projectingWithQuery();
mp911de

mp911de commented on Oct 7, 2020

@mp911de
Member

DTO projections work actually on top of the repository entity type in the sense that DTO's are a subset of entity properties. Additional properties aren't really expected here.

The following code should explain the underlying assumptions:

class Person {
    @Column("fn")
    String firstName;
}

class PersonDto {
   String firstName;
}

Assuming the firstName property maps onto the fn column in your database, then a derived query would apply proper fieldname mapping:

Flux<PersonDto> findBy();

resulting in the SQL:

SELECT fn FROM person;

If we now translate that behavior to String-based queries, what would the select look like for:

@Query("SELECT … FROM person");
Flux<PersonDto> findBy();

Is it SELECT fn FROM person or would it rather be SELECT fn AS firstName FROM person?

mp911de

mp911de commented on Oct 7, 2020

@mp911de
Member

Likely, using the domaintype -> DTO for derived query processing and reading directly into the DTO for string-based queries is a good middleground as for string queries the type declaration and @Query are pretty close. For derived queries, you typically don't have much control over the projected queries.

added 2 commits that reference this issue on Oct 8, 2020

#475 - Refine projection result mapping.

b8f4e8b

#475 - Polishing.

101725c
mp911de

mp911de commented on Oct 8, 2020

@mp911de
Member

That change is in place now.

added this to the 1.2 RC2 (2020.0.0) milestone on Oct 8, 2020
alesikov

alesikov commented on Oct 11, 2020

@alesikov
Author

Thank you for the amazing project

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @mp911de@alesikov

        Issue actions

          Projections doesn't work using data-repositories · Issue #475 · spring-projects/spring-data-r2dbc