在 spring boot 中使用 graphql-java 我无法在嵌套列表中查询数据

Posted

技术标签:

【中文标题】在 spring boot 中使用 graphql-java 我无法在嵌套列表中查询数据【英文标题】:On using graphql-java with spring boot I am unable to query data within nested Lists 【发布时间】:2020-01-08 12:12:04 【问题描述】:

我刚开始探索 graphql,所以在使用该框架时遇到了最初的问题。这篇文章中使用的代码托管在 github @https://github.com/samshers/graphQL-Starter 我的 api 的 graphql 架构如下:

schema 
 query: Query


type Query 
 allCities: [City]
 city(name: String): City
 state(name: String): State 


type City 
    name: String
    population: String
    state: State


type State 
    name: String
    population: String
    country: Country
    cities : [City]
 

type Country 
    name: String
    population: String

我要执行的查询是 -


  city(name: "BayArea") 
    name
    population
    state 
        name
        population
        cities  
            name
        
        country 
            name
            population
        
    
  

我得到的结果是 -


    "errors": [],
    "data": 
        "city": 
            "name": "BayArea",
            "population": "7200000",
            "state": 
                "name": "CA",
                "population": "39900000",
                "cities": [],
                "country": 
                    "name": "USA",
                    "population": "330000000"
                
            
        
    ,
    "extensions": null

问题在于这部分结果 -

“人口”:“39900000”,“城市”:[], “国家”:

我确实希望城市数组会相应地填充特定州的所有可用城市。 如果有人能指出问题是否与架构/查询或 jpa 映射有关,将不胜感激。如前所述,代码托管在 github @https://github.com/samshers/graphQL-Starter

【问题讨论】:

我看到您使用的是古代版本的 graphql-java-tools 及其 Spring Boot starter。这些工件的命名完全是一团糟……但新版本位于com.graphql-java-kickstart group id 下,因此您应该改用它们。请注意,Kickstarter 项目独立于 graphql-java(核心 Java 库)团队,以及他们自己的 Spring Boot starter。此外,您标记了 graphql-spqr 但您根本没有使用它。 【参考方案1】:

迟到总比不回答好。

延迟抓取问题

您的问题来自您的事务管理。这种关系

public class State 

    @OneToMany(cascade=CascadeType.ALL)
    @JoinColumn(name="state")
    List<City> cities;

被懒惰地获取。仅当访问列表时,JPA 才会填充州的城市列表。如果访问列表时没有事务在运行,则列表将保持为空。

州数据获取器stateRepository.findOne(stateName); 找到州对象,但不填充其城市。后来,当 graphql-java 框架尝试访问城市时,没有事务在运行。因此,城市列表保持为空。

如何解决

简单而肮脏的方法是强制 EAGER 获取:

public class State 

    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name="state")
    List<City> cities;

其他更好的解决方案包括告诉 graphql-java-tools 保持事务打开,直到响应被发回并且在这个问题的接受答案中描述:LazyInitializationException with graphql-spring

【讨论】:

以上是关于在 spring boot 中使用 graphql-java 我无法在嵌套列表中查询数据的主要内容,如果未能解决你的问题,请参考以下文章

在 spring boot 中使用 graphql-java 我无法在嵌套列表中查询数据

一种灵活的API设计模式:在Spring Boot中支持GraphQL

GraphQL + Spring Boot:如何收集(错误)指标?

拦截器在 Spring Boot GraphQL 中不起作用

错误:使用 Graphql 在 Spring Boot 中不可为空的类型是“ID”

再谈GraphQL之在spring boot项目中快速应用