Kyl*_*fro 5 java orm jpa jpql jpa-2.0
我有一个名为Surgery的JPA 2实体.它有一个名为transfusionUnits的成员,它是一个Integer.
数据库中有两个条目.执行此JPQL语句:
Select s.transfusionUnits from Surgery s
Run Code Online (Sandbox Code Playgroud)
产生预期的结果:
2
3
Run Code Online (Sandbox Code Playgroud)
以下语句产生5的预期答案:
Select sum(s.transfusionUnits) from Surgery s
Run Code Online (Sandbox Code Playgroud)
我希望以下语句的答案是2.5,但它返回2.0.
Select avg(s.transfusionUnits) from Surgery s
Run Code Online (Sandbox Code Playgroud)
如果我在另一个(Float)成员上执行语句,结果是正确的.有关为什么会发生这种情况的任何想法?我需要在JPQL中进行某种转换吗?这甚至可能吗?当然,我在这里遗漏了一些微不足道的东西.
首先,让我总结一下JPA 2.0规范中关于AVG的内容(有关完整内容,请参见4.8.5 SELECT子句中的聚合函数)
AVG函数将状态字段路径表达式作为参数,并计算组上的状态字段的平均值.state字段必须是数字,结果以double形式返回.
因此,在第一次阅读之后,我期待以下代码段传递:
Query q = em.createQuery("select avg(s.transfusionUnits) from Surgery s");
Double actual = (Double) q.getSingleResult();
assertEquals(2.5d, actual.doubleValue());
Run Code Online (Sandbox Code Playgroud)
但它没有,我得到2.0了结果(双倍,但不是预期的结果).
所以我查看了数据库级别并意识到SQL查询实际上没有返回2.5.事实上,这就是我的数据库文档中关于AVG的内容:
平均值(平均值).如果未选择任何行,则结果为NULL.仅在select语句中允许聚合.该返回的值是相同的数据类型作为参数.
我期待太多了.JPA会将结果作为Double返回,但它不会做任何魔术.如果查询未返回具有所需精度的结果,则不会在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());
Run Code Online (Sandbox Code Playgroud)
更新:在INT列上使用AVG时,似乎某些数据库(例如MySQL)确实返回带小数部分的值(这是有道理的,无论我在此处使用的数据库的记录行为如何).对于其他数据库,上面的演员可以在"方言"中处理(例如,参见HHK的HHH-5173),以避免在使用JPQL时数据库之间的可移植性问题.
| 归档时间: |
|
| 查看次数: |
7775 次 |
| 最近记录: |