2016-07-21 24 views
3

Wir versuchen JPA construct() API, um Daten in unsere Objekte zu verwenden, aber leider scheint es die Typumwandlung zu ignorieren:JPA Konstrukt für falsch Konstruktor suchen

CriteriaBuilder cb = this.entityManager.getCriteriaBuilder(); 
CriteriaQuery<ReportDto> q = cb.createQuery(ReportDto.class); 
q.select(cb.construct(DailyReportDto.class, r.get(createdYear), 
    r.get(KpiSnapshot_.createdDay), 
    cb.toLong(cb.avg(r.get(KpiSnapshot_.value))))); 

Ergebnisse in:

java.lang.NoSuchMethodException: DailyReportDto.<init>(java.lang.Integer, java.lang.Integer, java.lang.Double) 

was macht für mich keinen Sinn, denn toLong sollte verhindern, dass es nach einem Double sucht, oder?

Antwort

1

toLong und andere CriteriaBuilder-Methoden dieses Formulars erstellen keine neuen Ausdrücke oder ändern sie trotzdem - sie werden zum Umwandeln verwendet und ändern den generischen Typ des Ausdrucks. Dein Ausdruck wird immer noch b.avg (r.get (KpiSnapshot_.value)) sein, was immer noch ein Double sein wird.

Ihr Konstruktor muss bei Bedarf die Konvertierung von Double in Long durchführen.

+0

Ich bin mir nicht sicher, ob ich Ihre Erklärung bekomme. Auch wenn es nach dem ToLong-Aufruf ein Ausdruck ist, wird es immer noch ein Double zurückgeben? – Nitek

+0

ja. Es ist das Gleiche wie das Casting - es verändert nicht das Objekt selbst. Wenn also der Ausdruck ein Double zurückgeben würde, würde er es immer noch tun. Dies ist für andere Ausdrücke gedacht, z. B. für den Ausdruck , in dem Sie möglicherweise wissen, dass es sich um einen Long-Typ handelt, der zurückgegeben werden muss und als solche verwendet werden muss. – Chris

+0

Seltsam, aber macht Sinn (irgendwie). Aber sollte Expresion.as (Long.class) dann nicht funktionieren? Gemäß den Javadocs wird ein neues Expression-Objekt erstellt. Oder handelt es sich immer noch nur um einen typisierten Klon des ursprünglichen Ausdrucks? – Nitek