graphql-java-kickstart / graphql-java-tools

A schema-first tool for graphql-java inspired by graphql-tools for JS
https://www.graphql-java-kickstart.com/tools/
MIT License
812 stars 174 forks source link

Two different classes used for type Page: #343

Closed erDuo10 closed 9 months ago

erDuo10 commented 4 years ago
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.coxautodev.graphql.tools.SchemaParser]: Factory method 'schemaParser' threw exception; nested exception is com.coxautodev.graphql.tools.SchemaClassScannerError: Two different classes used for type Page:
- interface org.springframework.data.domain.Page:
|   return type of method public org.springframework.data.domain.Page com.erduo.FirstGraphql.resolver.Query.findAllAuthors(java.lang.Integer,java.lang.Integer)
|   return type of method public org.springframework.data.domain.Page com.erduo.FirstGraphql.resolver.Query.findAllMyAuthors(java.lang.Integer,java.lang.Integer)

- interface org.springframework.data.domain.Page:
|   return type of method public org.springframework.data.domain.Page com.erduo.FirstGraphql.resolver.Query.findAllBooks(java.lang.Integer,java.lang.Integer)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:640) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    ... 142 common frames omitted
Caused by: com.coxautodev.graphql.tools.SchemaClassScannerError: Two different classes used for type Page:
- interface org.springframework.data.domain.Page:
|   return type of method public org.springframework.data.domain.Page com.erduo.FirstGraphql.resolver.Query.findAllAuthors(java.lang.Integer,java.lang.Integer)
|   return type of method public org.springframework.data.domain.Page com.erduo.FirstGraphql.resolver.Query.findAllMyAuthors(java.lang.Integer,java.lang.Integer)

- interface org.springframework.data.domain.Page:
|   return type of method public org.springframework.data.domain.Page com.erduo.FirstGraphql.resolver.Query.findAllBooks(java.lang.Integer,java.lang.Integer)
    at com.coxautodev.graphql.tools.SchemaClassScanner.handleFoundType(SchemaClassScanner.kt:319) ~[graphql-java-tools-5.7.1.jar:na]
    at com.coxautodev.graphql.tools.SchemaClassScanner.handleFoundType(SchemaClassScanner.kt:293) ~[graphql-java-tools-5.7.1.jar:na]
    at com.coxautodev.graphql.tools.SchemaClassScanner.scanResolverInfoForPotentialMatches(SchemaClassScanner.kt:268) ~[graphql-java-tools-5.7.1.jar:na]
    at com.coxautodev.graphql.tools.SchemaClassScanner.handleRootType(SchemaClassScanner.kt:119) ~[graphql-java-tools-5.7.1.jar:na]
    at com.coxautodev.graphql.tools.SchemaClassScanner.scanForClasses(SchemaClassScanner.kt:77) ~[graphql-java-tools-5.7.1.jar:na]
    at com.coxautodev.graphql.tools.SchemaParserBuilder.scan(SchemaParserBuilder.kt:169) ~[graphql-java-tools-5.7.1.jar:na]
    at com.coxautodev.graphql.tools.SchemaParserBuilder.build(SchemaParserBuilder.kt:210) ~[graphql-java-tools-5.7.1.jar:na]
    at graphql.kickstart.tools.boot.GraphQLJavaToolsAutoConfiguration.schemaParser(GraphQLJavaToolsAutoConfiguration.java:115) ~[graphql-kickstart-spring-boot-autoconfigure-tools-6.0.0.jar:na]
    at graphql.kickstart.tools.boot.GraphQLJavaToolsAutoConfiguration$$EnhancerBySpringCGLIB$$555cbf8c.CGLIB$schemaParser$1(<generated>) ~[graphql-kickstart-spring-boot-autoconfigure-tools-6.0.0.jar:na]
    at graphql.kickstart.tools.boot.GraphQLJavaToolsAutoConfiguration$$EnhancerBySpringCGLIB$$555cbf8c$$FastClassBySpringCGLIB$$16f0171.invoke(<generated>) ~[graphql-kickstart-spring-boot-autoconfigure-tools-6.0.0.jar:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) ~[spring-context-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at graphql.kickstart.tools.boot.GraphQLJavaToolsAutoConfiguration$$EnhancerBySpringCGLIB$$555cbf8c.schemaParser(<generated>) ~[graphql-kickstart-spring-boot-autoconfigure-tools-6.0.0.jar:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_181]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_181]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_181]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_181]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    ... 143 common frames omitted

java code

import org.springframework.data.domain.Page;

import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import com.erduo.FirstGraphql.model.entity.business.Author;
import com.erduo.FirstGraphql.model.entity.business.Book;
import com.erduo.FirstGraphql.model.input.OffsetBasedPageRequest;
import com.erduo.FirstGraphql.service.AuthorService;
import com.erduo.FirstGraphql.service.BookService;

public class Query implements GraphQLQueryResolver {
    private BookService bookService;
    private AuthorService authorService;

    public Query(AuthorService authorService, BookService bookService) {
        this.authorService = authorService;
        this.bookService = bookService;
    }

    public Page<Book> findAllBooks(Integer skip, Integer first) {       
        System.out.println("--------findAllBooks");
        return bookService.findAllBooks(new OffsetBasedPageRequest(skip.intValue(), first.intValue()));
    }

    public Page<Book> findAllMyBooks(Integer skip, Integer first) {
        System.out.println("--------findAllMyBooks");
        return bookService.findAllBooksByUser(new OffsetBasedPageRequest(skip.intValue(), first.intValue()));
    }

    public Page<Author> findAllAuthors(Integer skip, Integer first) {
        System.out.println("--------findAllAuthors");
        return authorService.findAllAuthors(new OffsetBasedPageRequest(skip.intValue(), first.intValue()));
    }

    public Page<Author> findAllMyAuthors(Integer skip, Integer first) {
        System.out.println("--------findAllMyAuthors");
        return authorService.findAllAuthorsByUser(new OffsetBasedPageRequest(skip.intValue(), first.intValue()));
    }

    public long countAllBooks() {
        return bookService.countAllBooks();
    }

    public long countAllMyBooks() {
        return bookService.countAllBooksByUser();
    }

    public long countAllAuthors() {
        return authorService.countAllAuthors();
    }

    public long countAllMyAuthors() {
        return authorService.countAllAuthorsByUser();
    }
}

schema code

union SearchResult = Book | Author

type Page {
    number: Int
    size: Int
    totalPages: Int
    totalElements: Int
    content: [SearchResult]
}

type Book{
    id: ID!
    title: String!
    isbn: String!
    pageCount: Int
    author: Author
}

input CreateBookInput {
    title: String!
    isbn: String!
    pageCount: Int
    author: ID!
}

extend type Query {
    findAllBooks(skip: Int = 0, first: Int = 0) : Page!
    findAllMyBooks(skip: Int = 0, first: Int = 0) : Page!
    countAllBooks: Long!
    countAllMyBooks: Long!
}

extend type Mutation {
    newBook(input:CreateBookInput!) : Book!
    deleteBook(id: ID!) : Boolean
    updateBookPageCount(pageCount: Int!, id: ID!) : Book!
}

type Author {
  id: ID!
  firstName: String!
  lastName: String!
}

input CreateAuthorInput {
  firstName: String!
  lastName: String!
}

type Query {
  findAllAuthors(skip: Int = 0, first: Int = 0) : Page!
  findAllMyAuthors(skip: Int = 0, first: Int = 0) : Page!
  countAllAuthors: Long!
  countAllMyAuthors: Long!
}

type Mutation {
  newAuthor(input: CreateAuthorInput!) : Author!
}
foresx commented 4 years ago

@vojtapol , I have this problem too.

Is there any hack method to fix this problem?

foresx commented 4 years ago

My schema looks like this:

type ActivityLog {
    id: ID
    name: String
    eventTime: DateTime
    attachments: CommonAttachment
}

type Case {
    id: ID
    number: String
    attachments: [CommonAttachment]
}
kdevesh commented 2 years ago

@erDuo10 @foresx Did you get any resolution for this?

oryan-block commented 9 months ago

Here's a working example:

class TempTest {
    @Test
    fun test() {
        val schema = SchemaParser.newParser()
                .resolvers(Query())
                .dictionary(Book::class)
                .dictionary(Author::class)
                .schemaString(
                    """
                        union SearchResult = Book | Author

                        type Page {
                            content: [SearchResult]
                        }

                        type Book{
                            id: ID!
                            title: String!
                        }

                        type Author {
                            id: ID!
                            firstName: String!
                        }

                        type Query {
                            findAllBooks(skip: Int = 0, first: Int = 0) : Page!
                            findAllAuthors(skip: Int = 0, first: Int = 0) : Page!
                        }

                    """)
                .build()
                .makeExecutableSchema()
    }

    data class Page<T : SearchResult>(val content: List<T>)
    data class Book(val id: String, val title: String) : SearchResult
    data class Author(val id: String, val firstName: String) : SearchResult
    sealed interface SearchResult

    class Query : GraphQLQueryResolver {
        fun findAllBooks(skip: Int?, first: Int?): Page<SearchResult> = Page(listOf(Book("1", "asdja")))
        fun findAllAuthors(skip: Int?, first: Int?): Page<SearchResult> = Page(listOf(Author("1", "asdasd")))
    }
}