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

Field resolving with argument does not work? #171

Closed
nilshartmann opened this issue Aug 26, 2018 · 2 comments
Closed

Field resolving with argument does not work? #171

nilshartmann opened this issue Aug 26, 2018 · 2 comments
Labels
Milestone

Comments

@nilshartmann
Copy link

nilshartmann commented Aug 26, 2018

Version of graphl-java-tools: 5.2.3

In my schema I have a Type like this:

type Person {
  name: String!
  friends(friendName: String!): [Friend!]!
  # omit other fields...
}

For the friends field on Person I wrote an own GraphQLResolver:

public class PersonFieldResolver implements GraphQLResolver<Person> {
  public List<Friend> friends(Person p, String friendName) {
    // this is never inkoved due to Exception thrown at runtime (see below)
  } 
}

At runtime I receive the following Exception when adding friends to my query:

2018-08-26 11:09:09.942  WARN 67826 --- [nio-9000-exec-2] g.e.SimpleDataFetcherExceptionHandler    : Exception while fetching data (/person/friends) : Cannot construct instance of `nh.graphql.Person` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('klaus')
 at [Source: UNKNOWN; line: -1, column: -1]

java.lang.IllegalArgumentException: Cannot construct instance of `nh.graphql.Person` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('klaus')
 at [Source: UNKNOWN; line: -1, column: -1]
	at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3750) ~[jackson-databind-2.9.6.jar:2.9.6]
	at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:3678) ~[jackson-databind-2.9.6.jar:2.9.6]
	at com.coxautodev.graphql.tools.MethodFieldResolver$createDataFetcher$$inlined$forEachIndexed$lambda$1.invoke(MethodFieldResolver.kt:82) ~[graphql-java-tools-5.2.0.jar:na]
	at com.coxautodev.graphql.tools.MethodFieldResolver$createDataFetcher$$inlined$forEachIndexed$lambda$1.invoke(MethodFieldResolver.kt:20) ~[graphql-java-tools-5.2.0.jar:na]
	at com.coxautodev.graphql.tools.MethodFieldResolverDataFetcher.get(MethodFieldResolver.kt:146) ~[graphql-java-tools-5.2.0.jar:na]
	at graphql.execution.ExecutionStrategy.fetchField(ExecutionStrategy.java:258) [graphql-java-9.2.jar:na]
	at graphql.execution.ExecutionStrategy.resolveFieldWithInfo(ExecutionStrategy.java:199) [graphql-java-9.2.jar:na]
	at graphql.execution.AsyncExecutionStrategy.execute(AsyncExecutionStrategy.java:70) ~[graphql-java-9.2.jar:na]
	at graphql.execution.ExecutionStrategy.completeValueForObject(ExecutionStrategy.java:631) [graphql-java-9.2.jar:na]
	at graphql.execution.ExecutionStrategy.completeValue(ExecutionStrategy.java:413) [graphql-java-9.2.jar:na]
	at graphql.execution.ExecutionStrategy.completeField(ExecutionStrategy.java:363) [graphql-java-9.2.jar:na]
	at graphql.execution.ExecutionStrategy.lambda$resolveFieldWithInfo$0(ExecutionStrategy.java:201) [graphql-java-9.2.jar:na]
	at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:602) ~[na:1.8.0_73]
	at java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:614) ~[na:1.8.0_73]
	at java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:1983) ~[na:1.8.0_73]
	at graphql.execution.ExecutionStrategy.resolveFieldWithInfo(ExecutionStrategy.java:200) [graphql-java-9.2.jar:na]
	at graphql.execution.AsyncExecutionStrategy.execute(AsyncExecutionStrategy.java:70) ~[graphql-java-9.2.jar:na]
	at graphql.execution.Execution.executeOperation(Execution.java:158) ~[graphql-java-9.2.jar:na]
	at graphql.execution.Execution.execute(Execution.java:100) ~[graphql-java-9.2.jar:na]
	at graphql.GraphQL.execute(GraphQL.java:554) ~[graphql-java-9.2.jar:na]
	at graphql.GraphQL.parseValidateAndExecute(GraphQL.java:496) ~[graphql-java-9.2.jar:na]
	at graphql.GraphQL.executeAsync(GraphQL.java:470) ~[graphql-java-9.2.jar:na]
	at graphql.GraphQL.execute(GraphQL.java:401) ~[graphql-java-9.2.jar:na]

For me it seems, that MethodFieldResolver uses the wrong target type when deserializing the argument (it uses Person instead of String).

Defining a resolver function with an argument on root level works fine and also defining a field resolver without arguments on Person works as expected:

public class PersonFieldResolver implements GraphQLResolver<Person> {
  public List<Friend> allFriends(Person p) {
    // this is  inkoved as expected with a correctly initialized Person object

  return ...;
  } 
}

Update: it might be related to having more than one GraphQLResolver for the same data class:

  • If I only have one GraphQLResolver for my Dataclass (Person) it just works fine.
  • If I have multiple GraphQLResolvers added to my schema, the problem occures. After some debugging I found that in MethodFieldResolver.getIndexOffset() false is returned when having more than one resolver (as the field resolverInfo in base class FieldResolver then at runtime is MultiResolverInfo and not NormalResolverInfo)

Is this a bug? Or am I doing something wrong? Should multiple resolvers work? (Field resolvers without arguments seem to have no problems)

Thanks for your help!

@oliemansm
Copy link
Member

I created a unit test in the project to reproduce this issue and I indeed see the same error. I haven't used multiple resolvers for the same data class myself before, and not sure if it is intended to work with multiple resolvers this way actually. They are supported for other (root) types though, so would expect them to be supported in this case as well. Will mark it as a bug.

@oliemansm
Copy link
Member

Thanks for your investigation and the info about the getIndexOffset() value. Adding a check for MultiResolverInfo fixed the issue.

@oliemansm oliemansm added this to the 5.3.1 milestone Sep 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants