Skip to content

feat: add where relation attributes criteria expressions #96

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

Merged
merged 17 commits into from
Mar 14, 2019

Conversation

igdianov
Copy link
Collaborator

@igdianov igdianov commented Mar 12, 2019

fixes #76

This PR adds support for many-to-one and one-to-many entity attributes in where criteria expressions with variable parameter bindings, i.e.

Given the following query with many-to-one relation:

query($authorId: Long) {  
  Books(where: {
    author: {id: {EQ: $authorId}}
  }) {
    select {
      id
      title
      genre
      author {
        id
        name
      }
    }
  }
}
variables:  { "authorId": 1 }

will result in

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

And given the following query with one-to-many relation:

query {
  Authors(where: {
    books: {genre: {IN: NOVEL}}
  }) {
    select {
      id
      name
      books {
        id
        title
        genre
      }
    }
  }
}

will result in

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

It is possible to use compound criterias in where search expressions given:

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

Will return filtered inner collection result:

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

It is also possible to filter inner collections as follows:

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

will result in

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

@codecov
Copy link

codecov bot commented Mar 12, 2019

Codecov Report

Merging #96 into master will increase coverage by 1.1%.
The diff coverage is 92.3%.

Impacted file tree graph

@@             Coverage Diff             @@
##             master      #96     +/-   ##
===========================================
+ Coverage     65.06%   66.17%   +1.1%     
- Complexity      328      338     +10     
===========================================
  Files            37       37             
  Lines          1955     2022     +67     
  Branches        286      290      +4     
===========================================
+ Hits           1272     1338     +66     
+ Misses          556      555      -1     
- Partials        127      129      +2
Impacted Files Coverage Δ Complexity Δ
...graphql/jpa/query/schema/impl/PredicateFilter.java 96.87% <100%> (+0.57%) 4 <0> (ø) ⬇️
...a/query/schema/impl/QraphQLJpaBaseDataFetcher.java 74.24% <88%> (+2.12%) 104 <5> (+5) ⬆️
...jpa/query/schema/impl/GraphQLJpaSchemaBuilder.java 87.52% <93.33%> (+0.4%) 90 <8> (+5) ⬆️

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 2933500...56af9ce. Read the comment docs.

@codecov
Copy link

codecov bot commented Mar 12, 2019

Codecov Report

Merging #96 into master will increase coverage by 0.27%.
The diff coverage is 88.43%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master      #96      +/-   ##
============================================
+ Coverage     65.06%   65.34%   +0.27%     
- Complexity      328      348      +20     
============================================
  Files            37       37              
  Lines          1955     1962       +7     
  Branches        286      291       +5     
============================================
+ Hits           1272     1282      +10     
+ Misses          556      553       -3     
  Partials        127      127
Impacted Files Coverage Δ Complexity Δ
...ntures/graphql/jpa/query/example/books/Author.java 0% <ø> (ø) 0 <0> (ø) ⬇️
...s/graphql/jpa/query/example/starwars/CodeList.java 0% <ø> (ø) 0 <0> (ø) ⬇️
...s/graphql/jpa/query/example/starwars/CodeList.java 0% <ø> (ø) 0 <0> (ø) ⬇️
...ventures/graphql/jpa/query/example/books/Book.java 0% <ø> (ø) 0 <0> (ø) ⬇️
.../graphql/jpa/query/example/starwars/Character.java 0% <ø> (ø) 0 <0> (ø) ⬇️
...ures/graphql/jpa/query/example/starwars/Human.java 0% <ø> (ø) 0 <0> (ø) ⬇️
...ures/graphql/jpa/query/example/starwars/Human.java 0% <ø> (ø) 0 <0> (ø) ⬇️
.../graphql/jpa/query/example/starwars/Character.java 0% <ø> (ø) 0 <0> (ø) ⬇️
...graphql/jpa/query/schema/impl/PredicateFilter.java 96.87% <100%> (+0.57%) 4 <0> (ø) ⬇️
.../query/schema/impl/GraphQLJpaQueryDataFetcher.java 95.12% <100%> (-0.58%) 20 <1> (ø)
... and 6 more

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 2933500...9e74e7c. Read the comment docs.

@igdianov
Copy link
Collaborator Author

@molexx I think it is good to be merged with the last fix. Have you tried it? Let me know.

@molexx
Copy link
Contributor

molexx commented Mar 12, 2019

Thanks. Will be tested from our front-end project tomorrow, I'll let you know!

@molexx
Copy link
Contributor

molexx commented Mar 13, 2019

Thanks, this works but is a bit restricted in that you can only use a relationship of the first entity, after that you can only use simple attributes as before.

For example:

query {  
  Books(where: {
    author: {id: {EQ: 1}}
  }) {
    select {
      id
      title
      genre
      author {
        id
        name
      }
    }
  }
}

you can say 'author: {id: ' but you can't say 'author: {books: '.
Would it be possible to allow this please?

@igdianov
Copy link
Collaborator Author

@molexx This is not possible right now. I had to disable nested relationship attributes is search criteria expressions because it is not clear right now how to construct complex joins and predicates for Jpa queries to make it work correctly. If you have any ideas let me know.

I am also working on optimizing predicate building to avoid duplicating predicates in SQL where expressions. There is a strange caching issue that makes Hibernate cache first result for filtered collection. After that, it will keep returning the same result even if collection filter changes. I experience this via GraphiQL app only, but the unit tests work as expected..

@igdianov
Copy link
Collaborator Author

@molexx I am ready to merge this PR if there are no other comments. We can try to solve complex relation attribute criteria expressions later. I just want to be careful about it.

I have also resolved Hibernate object mapping caching issue by clearing session cache with entityManager.clear() before every query. Nothing else worked for me. It looks like a bug in Hibernate.

@molexx
Copy link
Contributor

molexx commented Mar 14, 2019

Yes this looks good to me, thanks.

Thanks for all your work on this. I hope we can find a way to allow nested relationships.

@molexx
Copy link
Contributor

molexx commented Mar 14, 2019

Continuing the conversation about nesting relationships in #97

@igdianov igdianov merged commit b296d8a into master Mar 14, 2019
@igdianov igdianov deleted the feat-where-relation-attribute-filter branch March 14, 2019 09:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Query help: filter inside relationships without returning data
2 participants