graphql-java и hibernate - lazy загружает отношения, которые даже не указаны в запросе - PullRequest
0 голосов
/ 28 сентября 2018

Я надеюсь, что кто-то испытал нечто подобное и может мне помочь:

Я использую graphql-java (и spring, graphql-java-tools и т. Д.) И 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который загружает только элементы, в итоге сначала выбирает все элементы в одном запросе, а затем выбирает всех владельцев в отдельном запросе (если владелец не совпадает в нескольких элементах, то он возвращается из кэша гибернации).

Поэтому я подумал, что graphql-java рекурсивно сканирует объекты, которые ему возвращаются, что приводит к извлечению прокси-серверов hibernate.

Могу ли я быть прав, или вы считаете, что моипроблема совершенно не связана с graphql-java?

ОБНОВЛЕНИЕ:

Я обнаружил, что это не имеет никакого отношения к graphql и вызвано гибернацией.Мои отношения настроены как LAZY, но Hibernate игнорирует это и делает запрос для каждого человека.Итак, сначала запрос, который получает все элементы, а затем запрос для каждого человека (n + 1).И я сам не получаю доступ к прокси.

Я создаю запрос, подобный этому (это kotlin):

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

1 Ответ

0 голосов
/ 02 октября 2018

Чтобы прояснить ситуацию, это не имеет ничего общего с GraphQL.

Hibernate по умолчанию загружает отношения один-к-одному.

Чтобы изменить это поведение, добавьте в поле person значение

@ OneToOne (fetch = FetchType.LAZY)

...