这使用了非常复杂的实体集合,该实体集合主要由JPA实体组成,但也包括代理和从API提取的实体。我只是用@GraphQLQuery
批注真正地注释了要尝试获取的基类,但是它进入了下面的层次结构,并在某个时候找到了一个静态HashMap<String, String[]>
且具有硬编码的属性。内容。 (我学会了不问...)此时,它引发了此异常,并且一切都停止了:
graphql.AssertException: Name must be non-null, non-empty and match [_A-Za-z][_0-9A-Za-z]* - was 'Map_String_String[]Scalar'
at graphql.Assert.assertValidName(Assert.java:58)
at graphql.schema.GraphQLScalarType.<init>(GraphQLScalarType.java:50)
at graphql.schema.GraphQLScalarType.<init>(GraphQLScalarType.java:45)
at io.leangen.graphql.util.Scalars.graphQLMapScalar(Scalars.java:325)
at io.leangen.graphql.generator.mapping.common.ObjectScalarAdapter.toGraphQLType(ObjectScalarAdapter.java:20)
at io.leangen.graphql.generator.mapping.common.ObjectScalarAdapter.toGraphQLType(ObjectScalarAdapter.java:16)
at io.leangen.graphql.generator.mapping.common.CachingMapper.toGraphQLType(CachingMapper.java:30)
at io.leangen.graphql.generator.OperationMapper.toGraphQLType(OperationMapper.java:179)
at io.leangen.graphql.generator.OperationMapper.toGraphQLType(OperationMapper.java:165)
at io.leangen.graphql.generator.OperationMapper.toGraphQLField(OperationMapper.java:138)
at io.leangen.graphql.generator.mapping.common.ObjectTypeMapper.lambda$getFields$3(ObjectTypeMapper.java:88)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1625)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at io.leangen.graphql.generator.mapping.common.ObjectTypeMapper.getFields(ObjectTypeMapper.java:89)
at io.leangen.graphql.generator.mapping.common.ObjectTypeMapper.toGraphQLType(ObjectTypeMapper.java:41)
at io.leangen.graphql.generator.mapping.common.ObjectTypeMapper.toGraphQLType(ObjectTypeMapper.java:33)
at io.leangen.graphql.generator.mapping.common.CachingMapper.toGraphQLType(CachingMapper.java:30)
at io.leangen.graphql.generator.OperationMapper.toGraphQLType(OperationMapper.java:179)
at io.leangen.graphql.generator.OperationMapper.toGraphQLType(OperationMapper.java:165)
at io.leangen.graphql.generator.OperationMapper.toGraphQLField(OperationMapper.java:138)
at io.leangen.graphql.generator.mapping.common.ObjectTypeMapper.lambda$getFields$3(ObjectTypeMapper.java:88)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1625)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at io.leangen.graphql.generator.mapping.common.ObjectTypeMapper.getFields(ObjectTypeMapper.java:89)
at io.leangen.graphql.generator.mapping.common.ObjectTypeMapper.toGraphQLType(ObjectTypeMapper.java:41)
at io.leangen.graphql.generator.mapping.common.ObjectTypeMapper.toGraphQLType(ObjectTypeMapper.java:33)
at io.leangen.graphql.generator.mapping.common.CachingMapper.toGraphQLType(CachingMapper.java:30)
at io.leangen.graphql.generator.OperationMapper.toGraphQLType(OperationMapper.java:179)
at io.leangen.graphql.generator.OperationMapper.toGraphQLType(OperationMapper.java:165)
at io.leangen.graphql.generator.OperationMapper.toGraphQLField(OperationMapper.java:138)
at io.leangen.graphql.generator.OperationMapper.lambda$generateQueries$0(OperationMapper.java:91)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at io.leangen.graphql.generator.OperationMapper.generateQueries(OperationMapper.java:92)
at io.leangen.graphql.generator.OperationMapper.<init>(OperationMapper.java:75)
at io.leangen.graphql.GraphQLSchemaGenerator.generate(GraphQLSchemaGenerator.java:868)
at com.ist.exam.graphql.services.GraphQLService.init(GraphQLService.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:349)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:300)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:133)
... 39 more
我不知道该名称是如何生成的,但是它以“ Map_String_String [] Scalar”的形式出现,然后抛出assertValidName。
我会用@GraphQLQuery(name="somethingClever")
注释该属性,但目前我们在整个公司共享的库中,并且在此处进行的更改必须经过更改请求和更改。
我尝试用withBasePackages
排除此代理程序包,但这似乎没有效果。这是尝试创建模式的方法:
GraphQLSchema schema = new GraphQLSchemaGenerator()
.withBasePackages("entities")
.withResolverBuilders(new AnnotatedResolverBuilder())
.withOperationsFromSingleton(examService)
.withValueMapperFactory(new JacksonValueMapperFactory())
.generate();
graphQL = GraphQL.newGraphQL(schema).build();
有人以前见过这些问题吗?我可以将软件包列入黑名单而不是将其列入白名单吗?例如withBasePackages("!proxies")
答案 0 :(得分:2)
它是a bug,因为永远不会生成一个无效的名称。我将在GraphQL SPQR的下一版本中立即解决此问题(在撰写本文时,当前版本为0.9.9)。
关于它最终如何变成Map_String_String[]Scalar
,这确实涉及……地图异常棘手,因为GraphQL中没有地图。这些选项基本上是将地图视为类型化的键/值对的列表,或仅视为未知的动态结构(即 JSON标量)。 SPQR支持两种方法,但默认情况下会将地图视为复杂(JSON)标量。为了保持对内部内容的某种了解,它将为每种基础Java类型生成一个名称不同的标量。为此,它必须为每个生成唯一的名称。对于您而言,它会找到一个Map<String, String[]>
,它会生成您看到的无效名称-Map_String_String[]Scalar
。
您可以通过注册一个可以捕获这种情况的自定义TypeMapper
或与此相关的所有复杂标量,并为其赋予相同的名称而不是唯一的名称来轻松解决此问题。
例如
public class CustomObjectScalarMapper extends ObjectScalarMapper {
private static final String OBJECT_SCALAR_NAME = "ObjectScalar";
@Override
protected String getTypeName(AnnotatedType type, BuildContext buildContext) {
return OBJECT_SCALAR_NAME;
}
@Override
protected String getInputTypeName(AnnotatedType type, BuildContext buildContext) {
return OBJECT_SCALAR_NAME;
}
}
并通过以下方式替换现有的ObjectScalarMapper
:
generator.withTypeMappers((conf, current) -> current.replace(ObjectScalarMapper.class, new CustomObjectScalarMapper()))
这样,所有复杂的标量都将称为ObjectScalar
,而您将不会遇到问题。
如果您希望更详细一点,也可以覆盖supports
方法。
一句话,您的生成器配置不需要将一堆东西设置为其默认值。
GraphQLSchema schema = new GraphQLSchemaGenerator()
.withBasePackages("entities")
.withResolverBuilders(new AnnotatedResolverBuilder())
.withOperationsFromSingleton(examService)
.withValueMapperFactory(new JacksonValueMapperFactory())
.generate();
等同于
GraphQLSchema schema = new GraphQLSchemaGenerator()
.withBasePackages("entities")
.withOperationsFromSingleton(examService)
.generate();