graphql-java и hibernate - ленивая загрузка отношений, которые даже не указаны в запросе

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

Я использую 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 игнорирует это и делает запрос для каждого человека. Итак, сначала запрос, который получает все элементы, а затем запрос для каждого человека (n + 1). А я сам к прокси не обращаюсь.

Я создаю такой запрос (это котлин):

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

person jah    schedule 27.09.2018    source источник


Ответы (1)


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

По умолчанию Hibernate с нетерпением загружает взаимно однозначные отношения.

Чтобы изменить это поведение, аннотируйте поле человека с помощью

@OneToOne (выборка = FetchType.LAZY)

person felipe_gdr    schedule 02.10.2018
comment
Я уже использую FetchType.LAZY. Но я думаю, что вы правы, что это не имеет ничего общего с GraphQL и вызвано самим спящим режимом. Но если бы он загружался очень быстро, я бы ожидал, что он сможет получить все объекты Person в одном запросе. В моем случае он выполняет запрос для каждого человека, что заставило меня поверить, что graphql сканирует свойства, вызывая выборку ленивых отношений. - person jah; 06.10.2018
comment
GraphQL Java будет вызывать геттеры только в том случае, если они являются частью запроса, это то, что PropertyDataFetcher делает. Как вы помечаете свойство person как LAZY? Я чувствую, что проблема может быть там. - person felipe_gdr; 06.10.2018
comment
Спасибо за ссылку, я этого и ожидал. Что заставило меня поверить, что это проблема с graphql, так это порядок выполнения запросов, но при отладке я мог видеть, что запросы были загружены до того, как мой преобразователь вернулся. Я обновил вопрос с помощью fetchtype, извините, что не упомянул об этом. Однако это отношение ManyToOne - person jah; 06.10.2018