当前位置: 首页 > 知识库问答 >
问题:

GraphQLJava和hibernate-惰性加载查询中甚至未指定的关系

樊博雅
2023-03-14

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

我正在使用graphql java(以及spring、graphql java工具等)和hibernate,我遇到了一个奇怪的问题:

每当我执行查询(或变异)并通过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
}

而一个只加载项的hibernate查询将首先获取一个查询中的所有项,然后在一个单独的查询中获取每个项的所有所有者(除非一个所有者在多个项中相同,否则它将从hibernate缓存返回)。

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

我的观点是否正确,或者您是否认为我的问题与graphql java完全无关?

更新:

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

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

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

共有1个答案

水昊阳
2023-03-14

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

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

要更改此行为,请使用注释“人员”字段

@OneToOne(fetch=FetchType.LAZY)

 类似资料:
  • 在使用Hibernate几年后,问这个问题有点尴尬... 我有一个master_table,它: null

  • 考虑以下实体: 的应该被延迟获取。问题是,当使用

  • 这组订单应该是惰性加载的,但我得到以下异常:org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常是org.hibernate.lazyInitializationException:未能懒洋洋地初始化Role:...,没有会话或会话被关闭 根本原因:org.hibernate.lazyInitializationExcept

  • 默认情况下,Hibernate支持一对多/多对一和多对多关联的惰性加载。但Hibernate不支持一对一关系的延迟加载。让我们为父场景和子场景提供以下示例。 一个人有一个地址父实体定义为。 子实体定义为 在上面的场景中,它应该是惰性加载,但实际上hibernate正在产生急切的加载。两个select语句同时激发1)select用于父实体,在本例中为Person;2)select用于子实体,在本例中

  • 我们目前有几个@OneToOne关系,由于已知的惰性加载的限制,它们总是会急切地从反方向获取。 为了启用逆关系的延迟加载,我正在尝试启用构建时字节码检测。 到目前为止我所做的... 这些关系现在不再急切地加载...但是它们也不会延迟加载,它们只是静默地返回null。 我尝试从实体中删除接口和字段,因为我不确定是否需要这样做,在此之后,我在启动时不再获得消息,并且默认情况下返回到急切加载。 我是不是

  • 我在应用程序中工作。流程和往常一样:。 我用注释了服务层类,从而将该类中的每个方法都标记为事务性的。在服务类中,我调用以获取某个域对象,然后将其转换为对象,该对象将传递给Controller。为了将域对象转换为,我编写了另一个自定义静态类(只有静态方法的类),如,它将进行此转换。 现在,域对象有一些子对象(),它被懒洋洋地加载。因此,当我在中访问子getter方法时,会发出一个额外的数据库调用,该