【问题标题】:graphql-java and hibernate - lazy loads relations that are not even specified in querygraphql-java 和 hibernate - 延迟加载甚至没有在查询中指定的关系
【发布时间】:2019-03-03 22:12:20
【问题描述】:

我希望有人经历过类似的事情并可以帮助我:

我正在使用 graphql-java(和 spring、graphql-java-tools 等)和休眠,但我遇到了一个奇怪的问题:

每当我执行查询(或突变)并通过 Hibernate 加载实体时,它都会自动延迟加载关系。我可以在查看 Hibernates 查询日志时看到这一点。

即使我没有在查询中加载该字段,甚至当我从架构中完全删除该字段时,也会发生这种情况。

例如,给定以下架构:

query {
    getAllItems: [Item!]!
}

Item {
    id: String!
    name: String!
    owner: Person!
}
Person {
    id: String!
    name: String!
    items: [Item!]!
}

还有一个 Hibernate 实体(伪代码):

@Entity
class Item {
    @Id
    private String id

    @Column
    private String name

    @ManyToOne(fetch = FetchType.LAZY)
    private: Person
    ...
}

以下查询:

getAllItems {
    id
    name
}

而一个只加载项目的休眠查询,最终会首先在一个查询中获取所有项目,然后在一个单独的查询中获取所有所有者(除非所有者在多个项目中相同,然后它的从休眠缓存中返回)。

所以我的想法是 graphql-java 递归地扫描返回给它的对象,这会导致休眠代理获取。

我能说得对吗,还是您认为我的问题与 graphql-java 完全无关?

更新:

我发现这与graphql无关,是hibernate引起的。我的关系设置为 LAZY,但 Hibernate 忽略了这一点,并对每个人进行查询。因此,首先是获取所有项目的查询,然后是每个人 (n+1) 的查询。而且我自己不访问代理。

我创建这样的查询(这是 kotlin):

entityManager
            .createQuery("SELECT i FROM Item i", Item::class.java)
            .setMaxResults(1000)
            .resultList

【问题讨论】:

    标签: java hibernate spring-boot graphql graphql-java


    【解决方案1】:

    为了清楚起见,这与 GraphQL 无关。

    默认情况下,Hibernate 急切地加载一对一的关系。

    要更改此行为,请在人员字段中添加注释

    @OneToOne(fetch = FetchType.LAZY)

    【讨论】:

    • 我已经在使用 FetchType.LAZY。但我认为你是对的,这与 GraphQL 无关,是由休眠本身引起的。但是,如果它急切加载,我希望它能够在一个查询中获取所有“Person”对象。在我的例子中,它对每个 Person 进行查询,这让我相信 graphql 正在扫描属性,导致获取惰性关系。
    • GraphQL Java 仅当 getter 是查询的一部分时才会调用它们,这就是 PropertyDataFetcher 所做的。您如何将 person 属性标记为 LAZY?我觉得问题可能就在那里。
    • 感谢您的链接,这也是我所期望的。是什么让我相信这是一个 graphql 问题,是执行查询的顺序,但是通过调试我可以看到查询在我的解析器返回之前加载。我已经用 fetchtype 更新了这个问题,很抱歉把它漏掉了。然而它是一个多对一关系
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多