I have a JPA 2 Entity named Surgery. It has a member named transfusionUnits that is an Integer.
There are two entries in the database. Executing this JPQL statement:
Select s.transfusionUnits from Surgery s
produces the expected result:
2
3
The following statement produces the expected answer of 5:
Select sum(s.transfusionUnits) from Surgery s
I expect the answer of the following statement to be 2.5, but it returns 2.0 instead.
Select avg(s.transfusionUnits) from Surgery s
If I execute the statement on a different (Float) member, the result is correct. Any ideas on why this is happening? Do I need to do some sort of cast in JPQL? Is this even possible? Surely I am missing something trivial here.
First, let me summarize what the JPA 2.0 specification says about AVG (see section 4.8.5 Aggregate Functions in the SELECT Clause for the full content)
So, after a first read, I was expecting the following snippet to pass:
But it didn’t, I was getting
2.0as result (a Double, but not the expected result).So I looked at the database level and realized that the SQL query was actually not returning
2.5. And indeed, this is what the documentation of my database says about AVG:I was expecting too much. JPA will return the result as a Double, but it won’t do any magic. If the query doesn’t return a result with the required precision, you won’t get it at the Java level.
So without changing the type of
transfusionUnits, I had to run this native query to get things working:Update: It appears that some database (e.g. MySQL) do return a value with a decimal part when using AVG on an INT column (which makes sense, regardless of the documented behavior of the database I used here). For other databases, the above cast could be handled
in the “dialect” (e.g. see HHH-5173 for Hibernate) to avoid portability issues between database when using JPQL.