Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit selection of nested properties #3352

Open
scordio opened this issue Feb 4, 2024 · 3 comments
Open

Limit selection of nested properties #3352

scordio opened this issue Feb 4, 2024 · 3 comments
Labels
type: enhancement A general enhancement

Comments

@scordio
Copy link
Contributor

scordio commented Feb 4, 2024

I'm not sure if I should report this in spring-data-jpa or spring-data-commons. I apologize in advance if this isn't the right place.

I experienced the following issue on Spring Data JPA with Hibernate, initially with Spring Boot 2.7.14 and Db2 for z/OS, but also reproduced with the latest Spring Boot (both GA and snapshot) and H2.

In the Interface-based Projections section of both the Spring Data JPA and Spring Data Commons reference guides, there is an example on how to use such projections recursively:

interface PersonSummary {

  String getFirstname();
  String getLastname();
  AddressSummary getAddress();

  interface AddressSummary {
    String getCity();
  }
}

If I use this interface in a repository, like:

interface PersonRepository extends Repository<Person, UUID> {

  Collection<PersonSummary> findPersonSummaryByLastname(String lastname);
}

The following query is executed:

select p1_0.firstname,p1_0.lastname,p1_0.city,p1_0.street,p1_0.zip_code from person p1_0 where p1_0.lastname=?

where street and zip_code are also selected although they are not required.

This seems to contradict what is mentioned in the Closed Projections section:

If you use a closed projection, Spring Data can optimize the query execution, because we know about all the attributes that are needed to back the projection proxy.

As a workaround, if I remove the nested interface in PersonSummary and concatenate the property names:

interface PersonSummaryNoNested {

  String getFirstname();

  String getLastname();

  String getAddressCity();
}

the following query is executed:

select p1_0.firstname,p1_0.lastname,p1_0.city from person p1_0 where p1_0.lastname=?

Reproducer: PersonRepositoryTest


Is this a bug or is it by design?

In case the example with the nested interface is not meant to be considered as a closed projection, would it make sense to highlight this detail in the documentation?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Feb 4, 2024
@mp911de mp911de added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Feb 5, 2024
@mp911de
Copy link
Member

mp911de commented Feb 5, 2024

Currently, this behavior is by design as we use top-level properties for the selection. We could introspect the projection for nested projections to limit the selection.

For the time being, using inlined, concatenated properties makes sense. We can revisit this enhancement somewhere in the future.

@mp911de mp911de changed the title Interface-based projection selects all attributes of inner projection Limit selection of nested properties Feb 5, 2024
@scordio
Copy link
Contributor Author

scordio commented Feb 5, 2024

Thank you for the feedback, @mp911de! Would you accept a small addition to the docs about it? I'd be happy to contribute.

Talking with colleagues, I realized this wasn't clear to many of them when looking at the PersonSummary example.

@christian-schlueter
Copy link

christian-schlueter commented Apr 10, 2024

Would love to see this revisited in the future - if the nested entity has relationships itself that are not part of the projection, they will also get queried in separate queries, so this can result in a lot of wasted DB resources.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants