Упорядочивание результатов по вычисленному значению в Hibernate

У меня есть таблица Player со столбцами id, name, wins, games_played. Я сопоставил его с классом Player. Я хочу выполнить следующий запрос в Hibernate (желательно с критериями, если это невозможно, с критериями HQL также поможет)

выберите * из списка игроков по (wins / games_played)

Я ожидаю получить список ‹Player›, отсортированный по их проценту побед.

Спасибо за ответ

Пало


person Palo    schedule 03.03.2010    source источник


Ответы (3)


Hibernate не поддерживает арифметические выражения в предложении order by. Цитирование раздела 14.12. Пункт group by документации Hibernate:

Ни предложение group by, ни предложение order by не могут содержать арифметические выражения.

И действительно, следующий запрос hql не вернет правильно упорядоченные результаты:

select p from Player p order by (p.wins/p.gamesPlayed) 

И я не думаю, что вы можете разделить org.hibernate.criterion.Property, поэтому API критериев не решит эту проблему.

Поэтому я бы предложил использовать вычисляемый атрибут (с формулой), например, с аннотациями:

private float wins;
private float gamesPlayed;
@Formula(value = "WINS/GAMESPLAYED")
private float ratio;

Это позволит выполнить следующий запрос с API критериев:

session.createCriteria(Player.class).addOrder(Order.desc("ratio"))
person Pascal Thivent    schedule 03.03.2010
comment
Это также работает в .NET с плавным отображением с использованием метода Formula (). - person andypaxo; 28.02.2011
comment
Примечание из будущего: Hibernate теперь поддерживает арифметические выражения в предложении order by: docs.jboss.org/hibernate/orm/5.4/userguide/html_single/ - person Stefan Haberl; 23.09.2020

Из документов Hibernate -

Функции SQL и агрегатные функции разрешены в предложениях Have и Order by, если они поддерживаются базовой базой данных.

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html#queryhql-ordering

Это означает, что вам нужно делать это на основе вашей базовой базы данных.

person Padmarag    schedule 03.03.2010
comment
Спасибо за ответ. Вы знаете, как это сделать с помощью критериев? - person Palo; 03.03.2010
comment
-1: вопрос касается арифметических выражений (а не функций SQL или агрегатных функций), которые НЕ поддерживаются в порядке следования. - person Pascal Thivent; 08.03.2010

Поздно к вечеринке, но это возможно с текущей версией Hibernate (5.4 в моем случае):

var cb = entityManager.getCriteriaBuilder();
var query = cb.createQuery(Player.class);
var root = query.from(Player.class);

query.orderBy(cb.asc(cb.quot(root.get("wins"), root.get("gamesPlayed"))));

return entityManager.createQuery(query).getResultList();
person Stefan Haberl    schedule 23.09.2020