graphql-java和hibernate-延迟加载甚至在查询中未指定的关系

时间:2018-09-27 23:37:49

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

我希望有人经历过类似的事情并能为我提供帮助:

我正在使用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无关,并且是由休眠引起的。我的关系设置为LAZY,但是Hibernate忽略了这一点,并为每个Person进行了查询。因此,首先执行查询以获取所有项,然后查询每个人员(n + 1)。而且我自己也无法访问代理。

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

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

1 个答案:

答案 0 :(得分:1)

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

默认情况下,Hibernate渴望加载一对一关系。

要更改此行为,请用

注释人员字段

@OneToOne(fetch = FetchType.LAZY)