JPA с нетерпением ждёт лучших практик - PullRequest
0 голосов
/ 01 декабря 2018

После некоторых исследований я нашел много материалов о том, как написать простой и эффективный код (с использованием JPQL), который:

  1. Позволяет быстро получать связанные объекты (например, с помощью JOIN FETCH).
  2. Разрешает разбиение на страницы на одном объекте.

Но когда дело доходит до их объединения - становится неясно, как сделать это эффективным и чистым способом.

  • Либо это нетерпеливое извлечение, которое работает, но нумерация страниц применяется в памяти (иначе HHH000104: firstResult / maxResults, заданный при извлечении коллекции; применение в памяти! )

  • Либо это работает разбиение на страницы, но активная выборка не работает (даже если resultSet действительно содержал связанные сущности), что приводит к дополнительным запросам к базе данных для извлечения связанных сущностей для каждой строки впартия.


Самое близкое, что на самом деле работает, это https://vladmihalcea.com/fix-hibernate-hhh000104-entity-fetch-pagination-warning-message/

Но меня удивило, есть ли более интуитивно понятный и чистыйРешение проблемы?

Вопрос : Существуют ли другие рекомендации по использованию нумерации страниц при активном извлечении связанных объектов?

Примечание Решение также должно предоставлять способ применения фильтров к данным, извлекаемым из базы данных.(например, JPQL WHERE предложение )

1 Ответ

0 голосов
/ 04 декабря 2018

Самый простой подход к этой проблеме - использовать два запроса:

  1. Первый запрос, в котором применяются условия , где и разбиение на страницы .Запрос возвращает только идентификаторы
  2. Во втором запросе вы используете идентификаторы, возвращенные в первом запросе, и делаете FETCH s для связанных сущностей.

Например, первыйquery:

String jpql = "SELECT user.id FROM User user WHERE user.name = 'John'"

Query q = em.createQuery(jpql); 
q.setFirstResult(0);
q.setMaxResults(10);

List<Long> ids = q.getResultList();

Второй запрос:

String jqpl = "SELECT user FROM User user JOIN FETCH user.address WHERE user.id IN (:ids)"
Query q = em.createQuery(jpql); 
q.setParameter("ids", ids);

List<User> users = q.getResultList();

Обратите внимание, если вам нужно упорядочить по некоторый столбец.Предложение order by должно присутствовать в двух запросах, потому что база данных не соблюдает порядок идентификаторов, который вы передаете параметру, когда база данных возвращает строки.

...