graphql-java-tools
graphql-java-tools copied to clipboard
Unable to match type definition (ListType{type=NonNullType{type=TypeName{name='String'}}}) with java type (interface java.util.List): Java class is not a List or generic type information was lost: interface java.util.List
I have the following (Kotlin) data class:
data class EntityMatch<T> (
val text: String,
val value: T?,
val start: Int,
val end: Int
)
Now I have a List<String> as generic type of the data class EntityMatch, like:
data class TestClass (
val match: EntityMatch<List<String>>
)
and create the GraphQL schema accordingly:
type StringListEntityMatch {
text: String!
value: [String!]
start: Int!
end: Int!
}
type TestClass {
match: StringListEntityMatch!
}
I get the following error when starting my application:
...
Caused by: graphql.kickstart.tools.SchemaClassScannerError: Unable to match type definition
(ListType{type=NonNullType{type=TypeName{name='String'}}}) with java type (interface java.util.List):
Java class is not a List or generic type information was lost: interface java.util.List
I suppose this has to do with using List as a generic type.
I'm using graphql-java-tools:6.1.0, the latest version.
Any idea on how to get this data type working in GraphQL? Thanks!
That is not a valid GraphQL schema. Did you mean something like this?
type TestClass {
match: EntityMatch!
}
type EntityMatch {
text: String!
value: [String!]
start: Int!
end: Int!
}
Thanks for your quick reply. Sorry, I tried to simplify the model in this question from a large code base. The actual schema looks like:
type StringListEntityMatch {
text: String!
value: [String!]
start: Int!
end: Int!
}
type TestClass {
match: StringListEntityMatch!
}
Will update the original question to prevent confusion.
FYI: we've tried a few workarounds:
-
Using Java
Arrayinstead of KotlinListworks. However, you lose all the goodness of KotlinListlike deep equality checks etc. In our case this was too painful.data class TestClass ( val match: EntityMatch<Array<String>> ) -
Create a copy of the class having the model defined with
Array<String>instead ofList<String>, and use this class only in the GraphQL layer and do conversions of the data between the application and the GraphQL layer. -
store the data as a comma separated list in a single string, and write a wrapper model
Matchesto work with itdata class TestClass ( val match: EntityMatch<Matches> ) data class Matches ( val matches: String // comma separated list with matches ) // create helper functions to create Matches from a List<String>, and to convert Matches into List<String>
In the end we settled with solution (3) which was best for our case.
Another workaround. Instead of:
input MainInput {
childs: [OneChildInput!]!
}
input OneChildInput {
id: ID
}
use this:
input MainInput {
childs: ManyChildsInput!
}
input ManyChildsInput {
childs: [OneChildInput!]!
}
input OneChildInput {
id: ID
}
and in code:
class ManyChildsInput(val childs: List<OneChildInput>)