3.2.6.2.4. Запросы с distinct

В JPQL запросах для экранов со списками сущностей, в которых включено постраничное отображение и возможна непредсказуемая модификация запроса универсальным фильтром или механизмом ограничений групп доступа, при отсутствии в запросе оператора distinct может возникать следующий эффект:

  • при объединении с коллекцией на уровне извлечения из базы данных возникает набор с дубликатами строк

  • на клиентском уровне в источнике данных дубликаты исчезают, т.к. попадают в мэп (java.util.Map)

  • при постраничном отображении на одной странице оказывается меньшее количество строк, чем запрошено, общее количество строк наоборот завышено.

Таким образом, рекомендуется в JPQL запросы браузеров включать предложение distinct, которое гарантирует отсутствие дубликатов записей при выборке из базы данных. Однако в некоторых серверах БД (в частности PostgreSQL) при большом количестве извлекаемых записей (более 10000) SQL запрос с distinct выполняется недопустимо долго.

Для решения этой проблемы в платформе реализована возможность корректной работы без distinct на уровне SQL. Данный механизм включается свойством приложения cuba.inMemoryDistinct, при активации которого выполняется следующее:

  • В JPQL запросе должен по-прежнему присутствовать select distinct

  • В DataManager из JPQL запроса перед отправкой в ORM distinct вырезается

  • После загрузки страницы данных на Middleware удаляются дубликаты и выполняются дополнительные запросы к БД для получения нужного количества строк, которые затем и возвращаются клиенту.