graphql-java-tools icon indicating copy to clipboard operation
graphql-java-tools copied to clipboard

Unable to find class for union type

Open orvillelim opened this issue 7 years ago • 10 comments

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();
    }
}

orvillelim avatar Oct 30 '18 06:10 orvillelim

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
}

orvillelim avatar Oct 30 '18 19:10 orvillelim

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?

orvillelim avatar Oct 30 '18 19:10 orvillelim

@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;
    }

amimehra avatar Nov 09 '18 08:11 amimehra

@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.

oliemansm avatar Nov 17 '18 13:11 oliemansm

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."

gustavkarlsson avatar Jul 27 '19 16:07 gustavkarlsson

Any updates on this issue?

arnabkd avatar Aug 20 '19 07:08 arnabkd

Guess not because I got this error on 6.0.1 as well

ubarua123 avatar Feb 25 '20 13:02 ubarua123

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.

eburi avatar Jul 08 '20 14:07 eburi

No updates yet. We welcome contributions though.

vojtapol avatar Jul 08 '20 17:07 vojtapol

I have a patch that fixes this if someone wants to incorporate it: discover-union-and-interface-members.patch

briankrug avatar Apr 09 '24 15:04 briankrug