Spring Boot Kotlin项目@GraphQLName注解失效问题求助
问题:@GraphQLName注解无法匹配GraphQL Schema中的字段
我用Spring Boot + Kotlin + GraphQL开发登录应用,遇到@GraphQLName注解不生效的问题:
GraphQL Schema定义
schema { query: Query mutation: Mutation } type Mutation{ requestOTP(credential: String!,authType: String!): String }
对应的Kotlin代码
@Controller class ResetPassword( @Autowired val userRepository: UserRepository ): GraphQLMutationResolver { @GraphQLName("requestOTP") fun reset(credential: String, authType: String): String{ // 业务代码逻辑 } }
核心报错信息
graphql.kickstart.tools.resolver.FieldResolverError: No method found as defined in schema <unknown>:44 with any of the following signatures (with or without one of [interface graphql.schema.DataFetchingEnvironment, class graphql.GraphQLContext] as the last argument), in priority order: com.auth.test.presentation.ResetPassword.requestOTP(~credential, ~authType) com.auth.test.presentation.ResetPassword.getRequestOTP(~credential, ~authType)
如果把方法名改成fun requestOTP,哪怕加上@GraphQLName("LOLnothingLOL")也能正常运行,但我想保留reset作为方法名,求解决办法。
我的build.gradle配置
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("org.springframework.boot") version "2.7.6" id("io.spring.dependency-management") version "1.1.0" kotlin("jvm") version "1.7.21" kotlin("plugin.spring") version "1.7.21" kotlin("plugin.jpa") version "1.7.21" } group = "com.dagger" version = "0.0.1" java.sourceCompatibility = JavaVersion.VERSION_11 repositories { mavenCentral() } dependencies { implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-graphql") implementation("com.graphql-java-kickstart:graphql-spring-boot-starter:14.1.0") runtimeOnly("com.graphql-java-kickstart:graphiql-spring-boot-starter:11.1.0") implementation("org.springframework.boot:spring-boot-starter-oauth2-client") implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server") implementation("org.springframework.boot:spring-boot-starter-security") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation ("org.springframework.boot:spring-boot-starter-log4j2") modules { module("org.springframework.boot:spring-boot-starter-logging") { replacedBy("org.springframework.boot:spring-boot-starter-log4j2", "Use Log4j2 instead of Logback") } } //jwt token implementation ("io.jsonwebtoken:jjwt:0.9.1") implementation("com.expedia.graphql:graphql-kotlin-schema-generator:1.3.4") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation("org.springframework.session:spring-session-core") runtimeOnly("com.mysql:mysql-connector-j") testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.springframework:spring-webflux") testImplementation("org.springframework.graphql:spring-graphql-test") testImplementation("org.springframework.security:spring-security-test") } tasks.withType<KotlinCompile> { kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "11" } } tasks.withType<Test> { useJUnitPlatform() }
报错原因
你同时引入了三套GraphQL相关依赖,导致框架解析逻辑冲突:
- Spring官方的
spring-boot-starter-graphql - GraphQL Java Kickstart的
graphql-spring-boot-starter - Expedia的
graphql-kotlin-schema-generator
不同框架对@GraphQLName注解的处理逻辑完全不同:
- Spring官方GraphQL不识别Kickstart的
@GraphQLName,它用@MutationMapping/@QueryMapping来绑定Schema字段 - Kickstart的
@GraphQLName本应生效,但依赖冲突导致Spring官方解析逻辑优先执行,注解被忽略
解决方案
方案一:统一使用Spring官方GraphQL框架(推荐)
- 移除Kickstart和graphql-kotlin的依赖,只保留
spring-boot-starter-graphql - 用Spring官方的
@MutationMapping注解替换@GraphQLName,指定name属性绑定Schema字段:
@Controller class ResetPassword( @Autowired val userRepository: UserRepository ) { @MutationMapping(name = "requestOTP") fun reset(credential: String, authType: String): String { // 业务代码逻辑 } }
方案二:统一使用GraphQL Java Kickstart框架
- 移除Spring官方的
spring-boot-starter-graphql和graphql-kotlin-schema-generator依赖 - 确认
@GraphQLName的包路径为graphql.annotations.annotationTypes.GraphQLName(Kickstart框架的注解) - 保持原有代码结构,注解即可正常生效:
@Controller class ResetPassword( @Autowired val userRepository: UserRepository ): GraphQLMutationResolver { @GraphQLName("requestOTP") fun reset(credential: String, authType: String): String { // 业务代码逻辑 } }
注意事项
- 不要同时混用多套GraphQL框架依赖,避免注解解析逻辑冲突
- 确认注解的包路径正确,不同框架的同名注解功能完全不同
内容的提问来源于stack exchange,提问作者XaFav
相关产品推荐
相关产品推荐

