Критерии спящего режима: разные объекты, а затем ограничение
У меня есть критерии, которые возвращают все данные, требуемые приложением, в основном:
Criteria criteria = session.createCriteria(Client.class);
criteria.createAlias("address", "address");
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.setFirstResult(init);
criteria.setMaxResults(max);
List<Client> clients = criteria.list();
Проблема заключается в том, что клиент/адрес отношения двунаправлен: на клиенте есть один адрес и один адрес может принадлежать более чем одному клиенту.
Я хочу получить "одиночные" клиентские объекты на основе их pk, конечно, некоторое количество клиентов, поскольку они отображаются в таблице.
Поскольку выполняются setFirstResult/setMaxResults, я получаю дублированные клиенты в уже применяемых ограничениях. После того, как был использован (уровень приложения как не групповой), hibernate получает избытки дублирующих клиентов, поэтому я заканчиваю тем, что меньше клиентов, что максимум указан в setMaxResults.
Невозможно группировать группу (группу проекций), поскольку она не будет возвращать все столбцы, требуемые в клиенте/адресах, только группа, к которой группируется запрос.
(Подводя итог, моя таблица имеет 100 результатов на странице, но после отбрасывания дубликатов у меня есть 98 результатов вместо 100...), потому что предел: LIMIT 0,100 применяется до спящих групп, когда он должен выполняться ПОСЛЕ)
Ответы
Ответ 1
Как указано в потоке, связанном с "Ashish Thukral", следующая строка решает следующее:
criteria.setFetchMode("address.clients", FetchMode.SELECT);
Это предотвращает соединение, которое вызывает проблему.
Конечно, можно удалить fetch = "join" из файла конфигурации xml, но это решение не влияет на другие места, где может быть извлечен beans.
Ответ 2
Если вы ищете Клиента на основе идентификатора следующим образом. Исходя из ваших критериев, нет необходимости в максимальном и начальном размере, поскольку он всегда возвращает одного клиента.
Criteria criteria = getSession().createCriteria(Client.class);
criteria .add(Restrictions.eq("id", yourClientId);
criteria.createAlias("address", "address");
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.setFirstResult(init);
criteria.setMaxResults(max);
List<Client> clients = criteria.list();
Если вы ищете адрес на основе идентификатора следующим образом.
Criteria criteria = getSession().createCriteria(Client.class);
criteria.createAlias("address", "address");
criteria .add(Restrictions.eq("address.id", yourAddressId);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
criteria.setFirstResult(init);
criteria.setMaxResults(max);
List<Client> clients = criteria.list();
Ответ 3
Если я правильно понимаю ваши отношения, у вас будет список клиентов в адресе и одном адресе в каждом классе Client Entity.
Так что, если вы просто хотите получить список клиентов, какое большое дело, вы не можете просто получить их от
Criteria criteria = session.createCriteria(Client.class);
criteria.setFirstResult(init);
criteria.setMaxResults(max);
List<Client> clients = criteria.list();
Почему вы создаете псевдоним и используете distinct_root_entity? Если вам нужно получить этот адрес, когда вы получите доступ к нему в своем DAO или ServiceImpl, Hibernate все равно получит его лениво для вас.
Исправьте меня, если я ошибаюсь.