spring-boot - 在将 graphql-java 与 spring boot 一起使用时,我无法在嵌套列表中查询数据
问题描述
我刚开始探索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
解决方案
迟到的回答总比没有回答好。
延迟获取问题
您的问题来自您的事务管理。这种关系
public class State {
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="state")
List<City> cities;
是懒惰地取来的。仅当访问列表时,JPA 才会填充州的城市列表。如果访问列表时没有事务在运行,则列表将保持为空。
State 数据获取器stateRepository.findOne(stateName);
会找到 state 对象,但不会填充其城市。后来,当 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
推荐阅读
- vim - VIM 中的自定义字体
- http - 为什么传统的 HTTP 不适合移动设备
- python - 如何使用 BeautifulSoup 在 IMDB 网站上抓取电影的“描述”?
- r - R-Shiny DT:动态高光
- terraform - terraform init 命令在我的 .tf 文件中失败
- django-rest-framework - 在同一视图集中放置和修补方法,listapi 不起作用
- javascript - 如何使用 js gmap 设置默认缩放?
- django - 基本模板中用于在位置之间切换的按钮
- javascript - 使用 JavaScript 通过动画更改字体大小
- python-3.x - 为什么玩家编号不在不同的列中?