2016-07-21 26 views
3

我們正在嘗試使用JPAS construct() API將數據映射到我們的對象,但不幸的是它似乎忽略類型轉換:JPA構建找錯構造

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))))); 

結果:

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

這對我沒有意義,因爲toLong應該阻止它尋找一個Double,不是嗎?

回答

1

toLong和其他表單的CriteriaBuilder方法不會創建新表達式或無論如何改變它們 - 它們用於投射,改變表達式的泛型類型。你的表達仍然是b.avg(r.get(KpiSnapshot_.value)),它仍然是一個Double。

如果需要,您的構造函數將需要處理將Double轉換爲Long。

+0

我不確定我是否接受你的解釋。即使在toLong調用後它是表達式,它仍然會返回Double? – Nitek

+0

是的。這與鑄造任何東西一樣 - 它不會改變對象本身。所以如果表達式要返回一倍,它仍然會。這是針對其他表達式的,例如表達式,您可能知道它將是返回的Long類型,並且需要像這樣使用它。 – Chris

+0

奇怪,但有道理(不知何故)。但是,不應該Expresion.as(Long.class)工作嗎?根據javadocs它創建一個新的Expression對象。還是它仍然只是一個原始表達式的類型克隆? – Nitek