Spring Boot GraphQL响应映射Data对象返回null问题排查
GraphQL响应映射为自定义Data对象返回null的问题排查
问题重现
执行GraphQL查询后,尝试将响应映射到自定义Data实体类时,最终得到的data对象为null。相关代码及输出如下:
查询与执行代码
String document = """query { entries(entry_ids: "12CA") { rcsb_id rcsb_accession_info { initial_release_date } audit_author { name } rcsb_primary_citation { pdbx_database_id_PubMed pdbx_database_id_DOI } } }"""; ClientGraphQlResponse response = graphQlClient.document("document").executeSync(); System.out.println("response: " + response); ClientResponseField field = response.field("data"); System.out.println("field: " + field); Data data = field.toEntity(Data.class); System.out.println("data: " + data);
执行输出
response: {data={entries=[{rcsb_id=12CA, rcsb_accession_info={initial_release_date=1992-10-15T00:00:00Z}, audit_author=[{name=Nair, S.K.}, {name=Christianson, D.W.}], rcsb_primary_citation={pdbx_database_id_PubMed=1910042, pdbx_database_id_DOI=null}}]}} field: org.springframework.graphql.client.DefaultClientResponseField@540b91dc data: null
实体类定义
@lombok.Data public class Data { public List<Entries> entries; } @Data public class Entries { public String rcsb_id; public RcsbAccessionInfo rcsb_accession_info; public List<AuditAuthor> audit_author; public RcsbPrimaryCitation rcsb_primary_citation; } @Data public class RcsbAccessionInfo { public String initial_release_date; } @Data public class AuditAuthor { public String name; } @Data public class RcsbPrimaryCitation { public Integer pdbx_database_id_PubMed; public String pdbx_database_id_DOI; }
问题原因
查询语句传递错误
代码中graphQlClient.document("document")传递的是字符串字面量"document",而非预先定义的document变量,这会导致实际发送的GraphQL查询无效(尽管输出显示有数据,大概率是测试时的代码误写)。实体类缺少无参构造函数
Lombok的@Data注解默认不会生成无参构造函数,而Spring GraphQL依赖的Jackson反序列化机制,需要无参构造函数来实例化实体对象,缺少的话会直接导致映射失败,返回null。
解决方案
修正查询语句传递
将graphQlClient.document("document")改为graphQlClient.document(document),确保传递正确的查询变量:ClientGraphQlResponse response = graphQlClient.document(document).executeSync();为实体类添加无参构造函数
在所有实体类上添加@NoArgsConstructor注解,配合@Data使用,确保Jackson能正常实例化对象:@lombok.Data @lombok.NoArgsConstructor public class Data { public List<Entries> entries; } @Data @NoArgsConstructor public class Entries { public String rcsb_id; public RcsbAccessionInfo rcsb_accession_info; public List<AuditAuthor> audit_author; public RcsbPrimaryCitation rcsb_primary_citation; } // 其他实体类同理添加@NoArgsConstructor(可选)简化映射方式
可以直接使用response.toEntity(Data.class)替代先获取data字段再映射的方式,Spring GraphQL会自动处理响应的外层data结构:Data data = response.toEntity(Data.class);
内容的提问来源于stack exchange,提问作者Enrico Morelli
相关产品推荐
相关产品推荐

