Skip to content

Unable to find class for union type #200

Closed

Description

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

Activity

  1. orvillelim commented on Oct 30, 2018

    @orvillelim
    Author

    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
    }
    
  2. orvillelim commented on Oct 30, 2018

    @orvillelim
    Author

    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?

  3. amimehra commented on Nov 9, 2018

    @amimehra

    @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;
        }
    
  4. oliemansm commented on Nov 17, 2018

    @oliemansm
    Member

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

  5. gustavkarlsson commented on Jul 27, 2019

    @gustavkarlsson

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

  6. arnabkd commented on Aug 20, 2019

    @arnabkd

    Any updates on this issue?

  7. ubarua123 commented on Feb 25, 2020

    @ubarua123

    Guess not because I got this error on 6.0.1 as well

  8. eburi commented on Jul 8, 2020

    @eburi

    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.

  9. vojtapol commented on Jul 8, 2020

    @vojtapol
    Member

    No updates yet. We welcome contributions though.

  10. briankrug commented on Apr 9, 2024

    @briankrug

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

  11. oryan-block commented on Oct 17, 2026

    @oryan-block
    Collaborator

    #854 covers the sealed case. If the class behind a union or interface is a Kotlin sealed class or interface, or a Java 17 sealed type, the scanner now uses the subclass named after each member. So no dictionary entries or dummy queries needed:

    sealed class Pet {
        data class NormalPet(val name: String) : Pet()
        data class WeirdPet(val classification: String) : Pet()
    }

    For plain class hierarchies there's no way to list the subclasses of Pet without scanning the classpath, so the dictionary is still the way to go (.dictionary(NormalPet::class.java, WeirdPet::class.java) or a SchemaParserDictionary bean like @amimehra mentioned). The error message already points there.

    Closing this. @briankrug's @JsonSubTypes patch is tracked in #862.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions