graphql-java-tools
graphql-java-tools copied to clipboard
Unable to find class for union type
com.coxautodev.graphql.tools.SchemaClassScannerError: Object type 'WeirdPet' is a member of a
known union, but no class could be found for that type name.
my schema
union Pet = NormalPet | WeirdPet
type WeirdPet {
id: Int
name: String
age: Int
classification: Classification
availableDate: Date
}
type NormalPet {
id: Int
type: Animal
name: String
age: Int
owner: Owner
availableDate: Date
}
type Query {
pets: [Pet]
}
Spring boot class
@ComponentScan
@EnableAutoConfiguration
@SpringBootApplication
public class AppGraphql {
public static void main(String[] args) {
SpringApplication.run(AppGraphql.class, args);
}
@Bean
public GraphQLSchema schema() {
return SchemaParser.newParser()
.files("petshop.graphqls", "Types.graphqls", "InputTypes.graphqls")
.resolvers(new Query(), new Mutation(), new Subscription(new NewsPublisher()))
.scalars(new ScalarDate())
.dictionary("WeirdPet", WeirdPet.class)
.build().makeExecutableSchema();
}
}
Found workaround in issue by making sure there's either query request or mutation request defined in schema that returns WeirdPet type
Before :
type Query {
pets: [Pet]
owner(id: Int): Owner
getAdoptablePet: [NormalPet]
getAdoptableWeirdPet: [NormalPet]
}
type Mutation {
createPet(name: String, age: Int, type: Animal, owner: OwnerInput) : NormalPet
addForAdoptPet(name: String, age: Int, type: Animal, availableDate: Date) : NormalPet
}
After
type Query {
pets: [Pet]
owner(id: Int): Owner
getAdoptablePet: [Pet]
getAdoptableWeirdPet: [WeirdPet]
}
type Mutation {
createPet(name: String, age: Int, type: Animal, owner: OwnerInput) : NormalPet
addForAdoptPet(name: String, age: Int, type: Animal, availableDate: Date) : NormalPet
addForAdoptPet(name: String, age: Int, classification: Classification, availableDate: Date) : WeirdPet
}
I guess we should still able to create union without creating a "request" that returns the specific union type in this case "WeirdPet" type. Is this a bug?
@villerdex Was facing similar issue and was able to solve by creating a bean of SchemaParserDictionary with union member classes. With your schema, it would look like:
@Bean
public SchemaParserDictionary getSchemaParser() {
SchemaParserDictionary dictionary = new SchemaParserDictionary();
dictionary.add(new HashMap() {{
put("WierdPet", WeirdPet.class);
put("NormalPet", NormalPet.class);
}});
return dictionary;
}
@villerdex Right now it searches for the types starting at the root resolvers. That could be improved by taking the union definition into account as well.
Same thing seems to happen for interfaces:
"Object type MyType implements a known interface, but no class could be found for that type name. Please pass a class for type MyType in the parser's dictionary."
Any updates on this issue?
Guess not because I got this error on 6.0.1 as well
Same in 7.0.1. I think this is a bug. It only seems to affect you if you happen to use a type in a union for the first time.
No updates yet. We welcome contributions though.
I have a patch that fixes this if someone wants to incorporate it: discover-union-and-interface-members.patch