首先,让我总结JPA 2.0规范说的话有关AVG(参见4.8.5 聚合函数在SELECT子句的全部内容)
的AVG函数接受的状态字段路径表达式作为参数并计算组中的状态字段的平均值。状态字段必须是数字,并且结果以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。只有在select语句中才允许聚集。 返回值与参数具有相同的数据类型。
我期待太多了。 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());
更新:看来,一些数据库(如MySQL的)就返回在INT列上使用AVG时有一个小数部分的值(这是有道理的,无论这里使用的数据库的文档行为如何)。对于其他数据库,可以在“方言”中处理 (例如,参见Hibernate的HHH-5173),以避免在使用JPQL时数据库之间的可移植性问题。
它不适用于我,我得到的错误应该是)而不是+符号。 – 2015-07-20 19:31:58
为openjpa工作,似乎它是提供程序依赖 – MarianP 2015-07-21 08:19:04