如何在 graphql-java-tools Resolver 中 @Autowire 一个 JPA 存储库

Posted

技术标签:

【中文标题】如何在 graphql-java-tools Resolver 中 @Autowire 一个 JPA 存储库【英文标题】:How to @Autowire a JPA repository in graphql-java-tools Resolver 【发布时间】:2020-06-10 13:31:32 【问题描述】:

我在 Kotlin 中使用 Spring JPA 和 GraphQL-Java-Kickstart 库集。 当我向我的应用发送查询时,它会抛出这个:

2020-02-26 18:51:42.707 ERROR 2672 --- [nio-8080-exec-7] g.k.e.error.DefaultGraphQLErrorHandler   : Error executing query Exception while fetching data (/createUser) : lateinit property userRepository has not been initialized

kotlin.UninitializedPropertyAccessException: lateinit property userRepository has not been initialized
at com.minerepo.minerepo.resolver.mutation.RootMutationResolver.createUser(RootMutationResolver.kt:16) ~[main/:na]

这是我的解析器:

@Component
class RootMutationResolver : GraphQLMutationResolver 
    @Autowired
    private lateinit var userRepository: UserRepository

    fun createUser(user: UserInput): User = userRepository.save(User(
            id = UUID.randomUUID().toString(),
            email = user.email,
            nick = user.nick
    ))

这是一个实体:

@Entity
data class User(
        @Id val id: String,
        @NotNull @Email var email: String,
        @NotBlank @Length(min=4, max=64) var nick: String
) : ProjectOwner // Table-per-class inheritance

这是输入类型类:

data class UserInput(
        var email: String,
        var nick: String
)

这是存储库:

@Repository
@Component
interface UserRepository : JpaRepository<User, String>

这是主类:

@SpringBootApplication
class MinerepoApplication 
    @Bean
    fun schema() : GraphQLSchema = SchemaParser.newParser()
            .file("schema.graphqls")
            .resolvers(RootQueryResolver(), RootMutationResolver())
            .build()
            .makeExecutableSchema()


fun main(args: Array<String>) 
    runApplication<MinerepoApplication>(*args)

【问题讨论】:

你可能需要做这样的事情:***.com/questions/57182703/… 所以最好使用UserRepository?而不是lateinit,并在调用时检查是否为null? 来自链接,是的 没有太大区别,现在查询只返回null 【参考方案1】:

你能在另一个组件(不是 GraphQL 组件)中自动装配 UserRepository 吗?

我认为你错过了 MinerepoApplication 类上的 @EnableJpaRepositories 注释。示例:

@SpringBootApplication
@EnableJpaRepositories(basePackageClasses = [MinerepoApplication::class])
class MinerepoApplication 
    @Bean
    fun schema() : GraphQLSchema = SchemaParser.newParser()
            .file("schema.graphqls")
            .resolvers(RootQueryResolver(), RootMutationResolver())
            .build()
            .makeExecutableSchema()

这将指示 Spring Data 扫描 MinerepoApplication 类包(和子包)以查找 JPA 存储库。

您不需要注释 @Repository@Component 通过 JPA 存储库接口。此外,@Repository 也可以像@Component 一样工作。

我还想补充一点,当您在组件中注入必要的依赖项时,您不应该在字段上使用@Autowired,您应该通过构造函数注入它们。示例:

@Component
class RootMutationResolver(
   private val userRepository: UserRepository
) : GraphQLMutationResolver 

    fun createUser(user: UserInput): User = userRepository.save(User(
            id = UUID.randomUUID().toString(),
            email = user.email,
            nick = user.nick
    ))

【讨论】:

它没有用。我可以在我的主类中连接存储库(我只在那里检查过),即使没有@EnableJpaRepositories 它也不为空 我让它这样工作: 1. 我使用构造函数将存储库注入解析器 2. 然后我将解析器注入我的应用程序类并使用实例而不是创建我认为它不起作用,因为我之前通过了我自己的实例,这可能是 Spring 看不到的。第二部分与您的答案的构造函数有帮助:)

以上是关于如何在 graphql-java-tools Resolver 中 @Autowire 一个 JPA 存储库的主要内容,如果未能解决你的问题,请参考以下文章

使用graphql-java-tools和graphql-spring-boot-starter处理错误。

在 graphql-java-tools 中禁用 GraphQL Introspection

graphql servlet 未使用 graphql-java-tools 启动(未找到模式文件?)

使用 graphql-java-tools 和 graphql-spring-boot-starter 处理错误

记录初学Spring boot中使用GraphQL编写API的几种方式

如何在python中将变量字符串输入re.search [重复]