Skip to content

Translate projected properties of the fluent query API into a fetchgraph. #2345

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

Closed
wants to merge 4 commits into from

Conversation

schauder
Copy link
Contributor

@schauder schauder commented Oct 26, 2021

When a property path based projection is specified we still return the root entity.
But we do provide a fetchgraph.
The JPA implementation will (should) load only the specified attributes eagerly.
It most likely will also load all other attributes from all selected tables.

Once we have infrastructure in place for for multilevel projections the same approach can and should be used for those.
Currently this is not the case.

Closes #2329
See spring-projects/spring-data-commons#2420

@schauder schauder requested review from gregturn and mp911de October 26, 2021 14:37
Copy link
Contributor

@gregturn gregturn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Impeccable work!

My comments were simple format opinions.

Question: Are we forced to the use Query DSL's impl class of AbstractJPAQuery so that we can get ahold of their setHint method?


@BeforeEach
void beforeEach() {
entityGraph = mock(EntityGraph.class, RETURNS_DEEP_STUBS);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Do we need a blank link here?

em.clear();

assertThat(users).extracting(User::getFirstname) //
.containsExactlyInAnyOrder( //
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally: I prefer the contains on the previous line instead of its own line.

em.clear();

assertThat(users).extracting(User::getFirstname) //
.containsExactlyInAnyOrder( //
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See earlier.


for (String property : properties) {

final String[] split = property.split("\\.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to convert properties into PropertyPath.

*/
public interface Projector {

AbstractJPAQuery<?, ?> apply(Class<?> domainType, AbstractJPAQuery<?, ?> query, @Nullable Set<String> properties);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Nullable doesn't work well with collections. We rather should have an empty collection.

.isThrownBy( //
() -> users.forEach( //
u -> u.getRoles().forEach(r -> { //
System.out.println(r.getName() //
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sysout?

() -> users.forEach( //
u -> u.getRoles().forEach(r -> { //
System.out.println(r.getName() //
); //
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are a lot of //

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I let Eclipse formatter have its way, I can't read the code anymore :-/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified the test so we need less // to make it readable.

@schauder schauder force-pushed the issue/2329-consider-property-paths branch 2 times, most recently from 82d845b to 1196a89 Compare October 27, 2021 13:56
private AbstractJPAQuery<?, ?> createSortedAndProjectedQuery() {

final AbstractJPAQuery<?, ?> query = this.finder.apply(this.sort);
projector.apply(entityType, query, properties);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we be consistent on using this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be consistent on not using this which is what we do in the rest of the code base, except for constructor and setters where parameters have the same names as fields.

this.entityManager = entityManager;
}

public void apply(Class<?> domainType, Q query, Set<String> properties) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be neat to turn this method into createEntityGraph and inverse the responsibilities. Instead of apply(…) here and the abstract method, it would be good to have more encapsulation and not carry the query type around.

Since this is all internal API, we're free to change it, but it would help to understand this processing better.

@mp911de mp911de self-assigned this Oct 29, 2021
@mp911de mp911de added this to the 2.6 GA (2021.1.0) milestone Oct 29, 2021
schauder and others added 2 commits October 29, 2021 12:02
…aph.

When a property path based projection is specified we still return the root entity.
But we do provide a fetchgraph.
The JPA implementation will (should) load only the specified attributes eagerly.
It most likely will also load all other attributes from all selected tables.

Once we have infrastructure in place for for multilevel projections the same approach can and should be used for those.
Currently this is not the case.

Closes #2329
Original pull request: #2345.
Rename Projector to EntityGraphFactory. Remove QuerydslProjector and TypedQueryProjector. Remove MappingContext creation.

See #2329
Original pull request: #2345.
@mp911de mp911de force-pushed the issue/2329-consider-property-paths branch from 1b41ffb to 811d2f1 Compare October 29, 2021 10:06
gregturn pushed a commit that referenced this pull request Nov 4, 2021
…aph.

When a property path based projection is specified we still return the root entity.
But we do provide a fetchgraph.
The JPA implementation will (should) load only the specified attributes eagerly.
It most likely will also load all other attributes from all selected tables.

Once we have infrastructure in place for for multilevel projections the same approach can and should be used for those.
Currently this is not the case.

Closes #2329
Original pull request: #2345.
gregturn pushed a commit that referenced this pull request Nov 4, 2021
Rename Projector to EntityGraphFactory. Remove QuerydslProjector and TypedQueryProjector. Remove MappingContext creation.

See #2329
Original pull request: #2345.
gregturn added a commit that referenced this pull request Nov 4, 2021
For some reason, EclipseLinkNamespaceUserRepositoryTests freezes. Can't figure out the source, so we are disabling it for now.

See #2329
Original pull request: #2345.
@gregturn gregturn closed this Nov 4, 2021
@gregturn gregturn deleted the issue/2329-consider-property-paths branch November 4, 2021 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for property paths when using fluent API projections.
3 participants