Решение, которое мы реализовали для того, чтобы собрать большое количество тяжелых объектов в разумные сроки и без переполнения памяти (я говорю об объектах с несколькими отношениями fetchType.eager, к сущностям, которые сами имеют нетерпеливые извлеченные отношения), заключалось в том, чтобы сначала выберите идентификаторы этих объектов, а затем выберите сами объекты на основе этих идентификаторов.
Пришло время оптимизировать наш код, и мы заметили (используя hibernate.show_sql=true
), что запрос, который мы использовали для сбора этих объектов (select a from A a where a.id in :ids
), преобразуется JPA / Hibernate в тысячи запросов вида select a from ...endless join list... where a.id = ?
Вопрос в следующем:
Почему JPA / Hibernate преобразует наш начальный запрос с предложением «in» в такое большое количество запросов с предложениями «=». Разве это не неэффективно? Если так, есть ли способ предотвратить это?
Вот как в нашем коде вызывается запрос:
Query q = this.getContext().createQuery("select a from A a where a.id in :ids");
q.setParameter("ids", idList);
return (List<A>) q.getResultList();