我们将 graphql-spqr 和 graphql-spqr-spring-boot-starter 用于一个新项目(使用 Spring DataJPA、hibernate 等)。
我们有一个这样的突变:
@Transactional
@GraphQLMutation
public Match createMatch(@NotNull @Valid MatchForm matchForm) {
Match match = new Match(matchForm.getDate());
match.setHomeTeam(teamRepository.getOne(matchForm.getHomeId()));
match.setAwayTeam(teamRepository.getOne(matchForm.getAwayId()));
match.setResult(matchForm.getResult());
matchRepository.save(match);
return match;
}
这种突变工作正常:
mutation createMatch ($matchForm: MatchFormInput!){
match: createMatch(matchForm: $matchForm) {
id
}
variables: {...}
我省略了变量,因为它们并不重要。如果我将其更改为:
mutation createMatch ($matchForm: MatchFormInput!){
match: createMatch(matchForm: $matchForm) {
id
homeTeam {
name
}
}
variables: {...}
我得到一个 LazyInitalizationException ,我知道为什么:
homeTeam 由 ID 引用并由teamRepository
. 返回的团队只是一个休眠代理。这对于保存新匹配很好,不需要更多。但是为了发回结果,GraphQL 需要访问代理并调用 match.team.getName()。但这显然发生在标有 的事务之外@Transactional
。
我可以使用 Team homeTeam teamRepository.findById(matchForm.getHomeId()).orElse(null); 修复它 match.setHomeTeam(主队);
Hibernate 不再加载代理,而是加载真实对象。但是由于我不知道 GraphQL 查询到底要求什么,所以如果以后不需要,急切地加载所有数据是没有意义的。如果 GraphQL 能够在@Transactional
.
对此有什么建议吗?
PS:我剥离了代码并进行了一些清理以使其更简洁。所以代码可能无法运行,但确实说明了问题。