Skip to content

QuerydslDataFetcher to specify which properties and associations to fetch #87

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
JamesPeters98 opened this issue Jul 7, 2021 · 7 comments
Assignees
Labels
in: data Issues related to working with data status: superseded Issue is superseded by another type: enhancement A general enhancement

Comments

@JamesPeters98
Copy link

I've just been having a play with the library testing it with my current GraphQL implementation using https://github.com/leangen/graphql-spqr

I've tried using the QuerydslDataFetcher like this by passing in the DataFetchingEnvironment:

var job =
        QuerydslDataFetcher.builder(owningJobDataFetcher)
            .many()
            .get(env.dataFetchingEnvironment);

Just to clarify should this be joining entities requested in the dataFetchingEnvironment.

e.g if the query requested a job with a customer like this:

job {
  customer {
    name
    id
  }
}

From a Job Entity with a Customer Entity mapped ManyToOne, should it be joining the customer entity in the query?

Because currently I'm seeing N+1 behaviour, thought I'd clarify if Joining is supposed to happen before I investigate if it's a Hibernate mapping issue instead.

@schauder
Copy link
Contributor

At least for *-1 relationships that is very reasonable.
I'll try to make it happen.

@rstoyanchev rstoyanchev added in: data Issues related to working with data type: enhancement A general enhancement labels Jul 15, 2021
@rstoyanchev rstoyanchev added this to the 1.0.0-M2 milestone Jul 15, 2021
@rstoyanchev
Copy link
Contributor

Scheduling tentatively.

@schauder
Copy link
Contributor

After a little investigation I realised that under the hood the QuerydslDataFetcher is not just using some Spring Data infrastructure but directly calling a repository.
Yeah, I know this should have been clear to start with.

Anyway, repositories deliberately do not have a way to specify an EntityGraph or similar dynamically. The discussion about this is here: spring-projects/spring-data-jpa#951

But it makes a lot of sense for GraphQL.
Calling @mp911de to discuss how to get out of this conflict.

@mp911de
Copy link
Member

mp911de commented Jul 15, 2021

That isn't something that we can solve already. We face demand for various types of projections (interface/DTO projections, limiting/expressing the properties to materialize) for Spring Data's Querydsl and Query-by-Example programming models so we should investigate how we can approach these requirements.

@mp911de
Copy link
Member

mp911de commented Jul 29, 2021

We're investigating means to express eager-loading/how to prevent loading relationships using Spring Data JPA with GraphQL.

@rstoyanchev rstoyanchev changed the title Question: Should QuerydslDataFetcher automatically Join JPA Entities QuerydslDataFetcher to automatically join JPA entities Jul 29, 2021
@rstoyanchev rstoyanchev added the status: blocked An issue that's blocked on an external project change label Jul 29, 2021
@rstoyanchev rstoyanchev modified the milestones: 1.0.0-M2, 1.0 Backlog Jul 29, 2021
@austinarbor
Copy link

austinarbor commented Aug 19, 2021

Fellow SPQR user here. I was able to solve this problem in my own application with the help of the Cosium/spring-data-jpa-entity-graph library. I can't post the exact code I wrote, but the general algorithm is this:

  1. Get all the query fields from the data fetching environment, so you get something like [id, name, child/id, child/name, child/subchild/id, ...] and then split each entry on /
  2. Get the Hibernate ManagedType for the root entity class the query begins with
  3. Fetch the Hibernate ManagedType for the root entity's class
  4. For each path array in step 1
    1. If metamodel does not contain path[0], ignore the path
    2. If the metamodel contains the path , but Attribute::isAssociation is false, ignore the path (we only care about including assocations in the entity graph)
    3. Otherwise, if the metamodel contains and node and it is an assocation, fetch the child managed entity from the metamodel and repeat for path[1], etc until you reach the end. If all steps return true, add the path to a list of entries
  5. In the end, you will get a list of association nodes [child, child/subchild]. Replace each / with .. so you get [child, child.subchild]
  6. com.cosium.spring.data.jpa.entity.graph.domain.EntityGraph = com.cosium.spring.data.jpa.entity.graph.domain.EntityGraphUtils.fromAttributePaths(paths)
  7. Use this in your JPA method

@mp911de mp911de changed the title QuerydslDataFetcher to automatically join JPA entities QuerydslDataFetcher to specify which properties and associations to fetch Oct 21, 2021
@mp911de mp911de removed the status: blocked An issue that's blocked on an external project change label Oct 22, 2021
@mp911de mp911de self-assigned this Oct 22, 2021
@rstoyanchev rstoyanchev removed this from the 1.0 Backlog milestone Oct 27, 2021
@rstoyanchev rstoyanchev added the status: superseded Issue is superseded by another label Oct 27, 2021
@rstoyanchev
Copy link
Contributor

rstoyanchev commented Oct 27, 2021

This issue is superseded by PR #168 which implements the required changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues related to working with data status: superseded Issue is superseded by another type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants