SPQR GraphQL出现FieldUndefined验证错误,请求协助排查
解决GraphQL FieldUndefined错误:Field 'find_by_id' in type 'Query' is undefined
嘿,这个错误我之前也踩过坑——核心问题就是你标注了@GraphQLQuery(name = "find_by_id")的方法,没有被正确映射到GraphQL的Query类型里。虽然代码里写了注解,但Schema生成过程中肯定哪里卡壳了,下面是我整理的排查和解决步骤,按顺序来试:
1. 先查手动编写的Schema文件(如果有的话)
如果你项目里有.graphqls这类手动定义的Schema文件,先打开看看Query类型里有没有定义find_by_id字段。比如必须要有这样的内容:
type Query { find_by_id(id: ID!): Event }
要是这里没写,就算Java方法加了注解,框架也没法把两者绑定起来,直接补上就行。
2. 检查Query类的注解和扫描配置
- 确保你的Query类被GraphQL框架识别为根查询解析器。比如如果用的是graphql-java-tools,要让类实现
GraphQLQueryResolver接口;如果是其他库,可能需要加@GraphQLRootQuery这类注解。 - 检查
@GraphQLQuery注解的包是否导对了——别把其他库的同名注解导进来了,比如要确认是你用的GraphQL框架提供的那个(比如graphql.annotations.annotationTypes.GraphQLQuery或者com.coxautodev.graphql.tools.GraphQLQuery)。 - 确认框架的扫描范围包含了这个Query类。比如Spring Boot项目里,要确保类在
@ComponentScan的范围内,或者手动把它注册为Bean。
3. 排查EJB注入的影响
你提到Schema生成代码里有@EJB private...,这很可能是问题所在:
- 如果你的Query类是EJB,得确保容器正确初始化了这个Bean。要是Bean没被实例化,GraphQL框架根本扫不到它的方法。
- 可以先做个测试:临时注释掉
@EJB注入,在findById方法里直接返回一个模拟的Event对象(比如return new Event(id, "test");),然后重启服务看错误是否消失。如果消失了,说明是EJB注入的配置有问题,得调整EJB的部署或者GraphQL框架和EJB容器的集成方式。
4. 验证生成的Schema内容
直接打印出生成的Schema,看看Query类型里到底有没有find_by_id字段。可以加一段代码调试:
GraphQLSchema schema = // 你的Schema生成代码 System.out.println("Query fields: " + schema.getQueryType().getFields());
如果输出里找不到find_by_id,那肯定是方法没被扫描到,回到步骤2重新检查注解和扫描配置。
5. 检查方法签名和返回类型
- 确认
findById方法的参数注解@GraphQLArgument(name = "id")没问题,参数类型Long是GraphQL支持的类型(ID类型可以自动映射Long)。 - 检查返回类型
Event是否被正确定义为GraphQL类型:比如Event类有没有加@GraphQLType注解,或者它的字段有没有被正确标注@GraphQLField(如果需要的话)。
6. 排查依赖或版本问题
- 如果你用的是较老版本的GraphQL Java框架,可能存在注解扫描的bug,试着升级到最新的稳定版本。
- 检查项目依赖,确保没有不同版本的GraphQL相关库冲突(比如
graphql-java、graphql-java-tools、graphql-spring-boot-starter这些版本要匹配)。
最后给你个正确的示例参考,确保你的Query类结构没问题:
import com.coxautodev.graphql.tools.GraphQLQueryResolver; import graphql.annotations.annotationTypes.GraphQLQuery; import graphql.annotations.annotationTypes.GraphQLArgument; import javax.ejb.EJB; public class EventQueryResolver implements GraphQLQueryResolver { @EJB private EventService eventService; // 确保EventService是正确部署的EJB @GraphQLQuery(name = "find_by_id") public Event findById(@GraphQLArgument(name = "id") Long id) { return eventService.findById(id); } }
然后注册这个Resolver到Schema里:
GraphQLSchema schema = SchemaParser.newParser() .file("schema.graphqls") .resolvers(new EventQueryResolver()) .build() .makeExecutableSchema();
按这些步骤排查下来,应该能解决这个FieldUndefined的问题。
内容的提问来源于stack exchange,提问作者Tinus Jackson
相关产品推荐
相关产品推荐

