GraphQL中实现Interface时陷入循环报错的问题求助
解决GraphQL Interface实现的循环报错问题
我来帮你搞定这个让人头疼的循环报错!先理清楚问题的根源:
错误原因分析
- 第一个错误提示找不到
FeaturedCourseDto对应的类,是因为它在GraphQL Schema里实现了Featurable接口,但你没在SchemaParserDictionary里显式注册这个类型; - 当你尝试添加
FeaturedCourseDto到字典时,又提示“value already present”,这是因为你的FeaturedCourseDto继承了FeaturedElementDto,而某些GraphQL Java库(比如GraphQL Java Tools)会自动扫描并注册父类的子类,导致你手动添加时出现重复; - 另外,你的Java代码里缺少和GraphQL中
Featurable接口对应的Java接口,这会让库无法正确关联接口和实现类。
分步解决方案
1. 添加Java版的Featurable接口
首先,创建和GraphQL接口字段对应的Java接口,让你的DTO类实现它:
public interface Featurable { UUID getGuid(); UUID getEntityGuid(); String getFriendly(); String getDescription(); String getInstitutionName(); String getInstitutionFriendly(); String getPrimaryImageUrlBase(); String getPrimaryImageUrlPath(); }
然后修改FeaturedElementDto实现这个接口:
@Getter @Setter @NoArgsConstructor public class FeaturedElementDto implements Featurable { private UUID guid; private String type; private UUID entityGuid; private String friendly; private String description; private String institutionName; private String institutionFriendly; private String primaryImageUrlBase; private String primaryImageUrlPath; private Integer orderNumber; }
FeaturedCourseDto继承自FeaturedElementDto,会自动实现Featurable接口,不需要额外修改。
2. 正确配置SchemaParserDictionary
既然库会自动注册子类,我们可以调整字典配置,只注册必要的类型,避免重复:
方案一:显式注册所有类型(处理重复问题)
如果自动注册导致重复,你可以先清空字典再添加,或者使用putIfAbsent逻辑(如果使用的是支持的版本):
@Bean public SchemaParserDictionary schemaParserDictionary() { SchemaParserDictionary dictionary = new SchemaParserDictionary(); // 先检查是否已存在,不存在再添加 dictionary.putIfAbsent("Featurable", Featurable.class); dictionary.putIfAbsent("FeaturedElementDto", FeaturedElementDto.class); dictionary.putIfAbsent("FeaturedCourseDto", FeaturedCourseDto.class); return dictionary; }
方案二:仅注册父类和接口
如果你的库会自动扫描子类,也可以只注册Featurable接口和FeaturedElementDto,让库自动发现FeaturedCourseDto:
@Bean public SchemaParserDictionary schemaParserDictionary() { return new SchemaParserDictionary() .add("Featurable", Featurable.class) .add("FeaturedElementDto", FeaturedElementDto.class); }
3. 验证类型映射正确性
确保GraphQL Schema中的每个type字段都和Java类的字段一一对应:
FeaturedElementDto和FeaturedCourseDto的所有字段在Java类中都有对应的getter/setter(你已经用了@Getter/@Setter,这没问题);- 继承关系在GraphQL和Java中保持一致:
FeaturedCourseDto在Schema里是独立的type实现Featurable,Java里继承FeaturedElementDto。
额外注意事项
当你返回[Featurable]类型的列表时,还需要配置TypeResolver来让GraphQL识别每个元素的具体类型(比如是FeaturedElementDto还是FeaturedCourseDto),示例代码如下:
@Component public class FeaturableTypeResolver implements TypeResolver { @Override public GraphQLObjectType getType(TypeResolutionEnvironment env) { Object object = env.getObject(); if (object instanceof FeaturedCourseDto) { return env.getSchema().getObjectType("FeaturedCourseDto"); } else if (object instanceof FeaturedElementDto) { return env.getSchema().getObjectType("FeaturedElementDto"); } throw new IllegalArgumentException("Unknown type: " + object.getClass().getName()); } }
这样应该就能解决你的循环报错问题啦!
内容的提问来源于stack exchange,提问作者TylerTwoForks
相关产品推荐
相关产品推荐

