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

fix: build join fetch from selection graph #137

Merged
merged 1 commit into from
May 6, 2019

Conversation

igdianov
Copy link
Collaborator

@igdianov igdianov commented May 6, 2019

This PR builds a join fetch graph from query selection tree to avoid Hibernate error: query specified join fetching, but the owner of the fetched association was not present in the select list

Given the following query:

{
  Humans(where: {
    friends: {
      name: {LIKE: "R2-D2"}
    }, 
    favoriteDroid: {
      primaryFunction: {
        function: {EQ: "Protocol"}
      }
    }
  }) {
    select {
      id
      name
      homePlanet
      favoriteDroid {
        name
        primaryFunction {
          function
        }
      }
      friends {
        name
        friends {
          name
        }
      }
    }
  }
}

The builder will traverse the selection graph to apply an explicit fetch join for each relation, after that it will reuse existing joins to apply where search criteria expressions.

As a result the query will create a fetch join for each relation in the selection to fetch the related data and add where criteria restrictions to another fetch join to avoid filtering graph collections, i.e.

query {
  Authors(where: {
    books: {
      title: {LIKE: "War"}
    }
  }) {
    select {
      id
      name
      books {
        id
        title
        genre
      }
    }
  }
}

The following JPQL query will be created with extra fetch join to retrieve full books collection:

select distinct Author from Author as Author 
    inner join fetch Author.books as generatedAlias0 
    inner join fetch Author.books as generatedAlias1 
    where lower(generatedAlias0.title) like :param0 
    order by Author.id asc

The result books collection containing book with title LIKE "War" will not be filtered:

{
  "data": {
    "Authors": {
      "select": [
        {
          "id": 1,
          "name": "Leo Tolstoy",
          "books": [
            {
              "id": 2,
              "title": "War and Peace",
              "genre": "NOVEL"
            },
            {
              "id": 3,
              "title": "Anna Karenina",
              "genre": "NOVEL"
            }
          ]
        }
      ]
    }
  }
}

If you omit books in the selection, i.e.

  Authors(where: {
    books: {
      title: {LIKE: "War"}
    }
  }) {
    select {
      id
      name
      # books {
      #   id
      #   title
      #   genre
      # }
    }
  }
}

The JPQL query will not contain extra fetch join for books:

select distinct Author from Author as Author 
   inner join fetch Author.books as generatedAlias0 
   where lower(generatedAlias0.title) like :param0 
   order by Author.id asc

And the result:

{
  "data": {
    "Authors": {
      "select": [
        {
          "id": 1,
          "name": "Leo Tolstoy"
        }
      ]
    }
  }
}

Verified

This commit was signed with the committer’s verified signature.
Aaron1011 Aaron Hill
@igdianov igdianov self-assigned this May 6, 2019
@igdianov igdianov added the bug label May 6, 2019
@codecov
Copy link

codecov bot commented May 6, 2019

Codecov Report

Merging #137 into master will increase coverage by 0.12%.
The diff coverage is 89.28%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #137      +/-   ##
============================================
+ Coverage     68.15%   68.27%   +0.12%     
- Complexity      428      432       +4     
============================================
  Files            33       33              
  Lines          2201     2219      +18     
  Branches        325      330       +5     
============================================
+ Hits           1500     1515      +15     
- Misses          569      571       +2     
- Partials        132      133       +1
Impacted Files Coverage Δ Complexity Δ
...a/query/schema/impl/QraphQLJpaBaseDataFetcher.java 71.39% <100%> (+0.26%) 144 <4> (+1) ⬆️
...hql/jpa/query/schema/impl/JpaPredicateBuilder.java 51.82% <75%> (+1.18%) 55 <0> (+3) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 764c439...5d4373c. Read the comment docs.

@igdianov igdianov merged commit d452620 into master May 6, 2019
@igdianov igdianov deleted the igdianov-fix-join-fetch branch May 6, 2019 06:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant