Во-первых, позвольте мне подвести итог, что спецификации JPA 2.0 говорит о AVG (смотрите раздел 4.8.5 агрегатные функции в SELECT, п для полного содержания)
Функция AVG принимает путь состояния поля выражение в качестве аргумента и вычисляет среднее значение поля sate над группой. Поле состояния должно быть числовым, а результат - returnd как Double.
Таким образом, после первого чтения, я ожидал, что следующий фрагмент кода, чтобы передать:
Query q = em.createQuery("select avg(s.transfusionUnits) from Surgery s");
Double actual = (Double) q.getSingleResult();
assertEquals(2.5d, actual.doubleValue());
Но это не так, я получал 2.0
как результат (двойной, но не ожидаемый результат).
Итак, я посмотрел на уровень базы данных и понял, что SQL-запрос фактически не возвращался 2.5
. И действительно, это то, о чем говорит документация моей базы данных о AVG:
Среднее (среднее) значение. Если строки не выбраны, результат будет NULL. Агрегаты разрешены только в некоторых операторах. Возвращаемое значение имеет тот же тип данных, что и параметр.
Я ожидал слишком многого. JPA вернет результат как Двойной, но он не сделает никакой магии. Если запрос не возвращает результат с требуемой точностью, вы не получите его на уровне Java.
Так что без изменения типа transfusionUnits
, я должен был запустить этот родной запрос, чтобы получить все работает:
Query q = em.createNativeQuery("SELECT AVG(CAST(s.transfusionUnits as double)) from Surgery s");
Double actual = (Double) q.getSingleResult();
assertEquals(2.5d, actual.doubleValue());
Update: Оказывается, что некоторые базы данных (например, MySQL) действительно возвращают значение с десятичной частью при использовании AVG в столбце INT (что имеет смысл, независимо от документированного поведения базы данных, которую я использовал здесь). Для других баз данных приведенный выше листинг может обрабатываться в диалекте (например, см. HHH-5173 для Hibernate), чтобы избежать проблем с переносимостью между базой данных при использовании JPQL.
Это не работает для меня, я получаю ошибку, которая должна быть), а не знак +. –
работал для меня с openjpa, кажется, что он зависит от поставщика – MarianP