Zuerst lassen Sie mich zusammenfassen, was die JPA 2.0-Spezifikation sagt über AVG
Die AVG-Funktion nimmt einen Zustand Feldbahn (Abschnitt 4.8.5 Aggregatfunktionen in der SELECT-Klausel für den vollständigen Inhalt sehen) Ausdruck als Argument und berechnet den Durchschnittswert des sate-Feldes über die Gruppe. Das Statusfeld muss numerisch sein und das Ergebnis wird als Double zurückgegeben.
So, nach einem ersten Lese, erwarte ich das folgende Snippet passieren:
Query q = em.createQuery("select avg(s.transfusionUnits) from Surgery s");
Double actual = (Double) q.getSingleResult();
assertEquals(2.5d, actual.doubleValue());
Aber es ging nicht, ich war 2.0
als Ergebnis zu erzielen (ein Double, aber nicht das erwartete Ergebnis).
Also schaute ich auf die Datenbank-Ebene und erkannte, dass die SQL-Abfrage tatsächlich 2.5
nicht zurückgegeben wurde. Und tatsächlich, das ist, was die Dokumentation meiner Datenbank über AVG sagt:
Der durchschnittliche (Mittelwert) Wert. Wenn keine Zeilen ausgewählt sind, ist das Ergebnis NULL. Aggregate sind nur in ausgewählten Anweisungen zulässig. Der zurückgegebene Wert hat denselben Datentyp wie der Parameter.
Ich habe zu viel erwartet. JPA wird das Ergebnis als Double zurückgeben, aber es wird keine Magie wirken. Wenn die Abfrage kein Ergebnis mit der erforderlichen Genauigkeit zurückgibt, erhalten Sie sie nicht auf Java-Ebene.
Also ohne die Art der transfusionUnits
zu ändern, hatte ich diese nativen Abfrage auszuführen Dinge zum Laufen zu bringen:
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: Es scheint, dass einige Datenbank (zB MySQL) ein kehre Wert mit einem Dezimalteil, wenn AVG für eine INT-Spalte verwendet wird (was sinnvoll ist, unabhängig vom dokumentierten Verhalten der Datenbank, die ich hier verwendet habe). Für andere Datenbanken könnte die obige Umwandlung im "Dialekt" gehandhabt werden (z. B. siehe HHH-5173 für Hibernate), um Portabilitätsprobleme zwischen Datenbanken bei der Verwendung von JPQL zu vermeiden.
Es funktioniert nicht für mich, ich bekomme Fehler, dass es sein sollte), anstatt + Zeichen. –
arbeitete für mich mit openjpa, scheint es Provider abhängig – MarianP