2015-10-14 35 views
1

Here my changes base on Ish Answer:瞭如何通過JPA的Java

public List<TopUpRAMSInfo> listadoTOPUP2(Date fechaI, Date fechaF) { 
     List<TopUpRAMSInfo> lista; 
     CriteriaQuery<TopUpRAMSInfo> data = cb.createQuery(TopUpRAMSInfo.class); 
     Root<TopUpRAMS> c = data.from(TopUpRAMS.class); 
     data.select(cb.construct(TopUpRAMSInfo.class, 
       c.get("deviceId"), 
       cb.sum(c.get("rechargeValue")) 
     ) 
     ); 
     data.where(cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI), 
       cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF) 
     ); 
     data.groupBy(c.get("deviceId")); 
     TypedQuery<TopUpRAMSInfo> datos = emDAO.createQuery(data); 
     lista = datos.getResultList(); 
     return lista; 
    } 

Now im having this error: java.lang.IllegalArgumentException: An exception occured looking on class: class ENTITY.TopUpRAMSInfo for constructor using selection criteria types as arguments. If this CriteriaQuery was not intended to be a constructor query please verify that the selection matches the return type.

----- ORIGINAL POST -----

我遇到一些問題,這樣做創建SUM和GROUP條件查詢。這是我嘗試構建的第一個真正的程序,我需要基於另一個領域總結一個領域。

這裏是我到目前爲止的代碼(注意:TopUpRAMS是我的實體和emDAO是我的實體管理器。

public List<TopUpRAMS> listadoTOPUP2(Date fechaI, Date fechaF) { 
    List<TopUpRAMS> lista; 

    CriteriaQuery<TopUpRAMS> data = cb.createQuery(TopUpRAMS.class); 
    Root<TopUpRAMS> c = data.from(TopUpRAMS.class); 

    data.multiselect(c.get("deviceId"), cb.sum(c.get("rechargeValue"))); 
    data.where(cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI)); 
    cb.and(cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF)); 
    data.groupBy(c.get("deviceId")); 

    TypedQuery<TopUpRAMS> datos = emDAO.createQuery(data); 
    lista = datos.getResultList(); 
    return lista; 
} 

回答

7

有一個與你如何構建你的CriteriaQuery中的WHERE部分問題。 這種表達是唯一一個被添加到WHERE子句:

cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI) 

但不是這一個:

cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF) 

任何ff。可以解決此問題:

  1. 使用cb.and():

    data.where(cb.and(
         cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI), 
         cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF) 
        ) 
    ); 
    
  2. CriteriaQuery.where()可以接受可變數目的 型表達的參數,它們將使用結合進行組合(和 運營商)。所以,我們並不需要使用cb.and():

    data.where(cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI), 
        cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF) 
    ); 
    

還有與你CriteriaQuery中使用的類型的問題。您通過2個字段的data.multiselect()進行投影,並且這不會轉換爲TopUpRams實體。

有3種方法做一個多選/投影:

  1. CriteriaQuery中類型將是對象[]

    CriteriaQuery<Object[]> data = cb.createQuery(Object[].class); 
    Root<TopUpRAMS> c = data.from(TopUpRAMS.class); 
    data.multiselect(c.get("deviceId"), cb.sum(c.get("rechargeValue"))); 
    
  2. CriteriaQuery中類型將是元組

    CriteriaQuery<Tuple> data = cb.createTupleQuery(); 
    Root<TopUpRAMS> c = data.from(TopUpRAMS.class); 
    data.multiselect(c.get("deviceId"), cb.sum(c.get("rechargeValue"))); 
    
  3. 使用構造函數

    CriteriaQuery<TopUpRAMSInfo> data = cb.createQuery(TopUpRAMSInfo.class); 
    Root<TopUpRAMS> c = data.from(TopUpRAMS.class); 
    data.select(cb.construct(TopUpRAMSInfo.class, 
         c.get("deviceId"), 
         cb.sum(c.get("rechargeValue")) 
        ) 
    ); 
    

    爲此,你需要創建一個單獨的類來表示你的查詢結果的 類型(它沒有成爲一個實體):

    public class TopUpRAMSInfo { 
        private Long deviceId; 
        private Double sumRechargeValue; 
    
        public TopUpRAMSInfo(Long deviceId, Double sumRechargeValue) { 
         this.deviceId = deviceId; 
         this.sumRechargeValue = sumRechargeValue; 
        } 
        ... 
    } 
    

所以這裏有一個樣本修復您的方法:

public List<TopUpRAMSInfo> listadoTOPUP2(Date fechaI, Date fechaF) { 

    List<TopUpRAMSInfo> lista; 

    CriteriaQuery<TopUpRAMS> data = cb.createQuery(TopUpRAMSInfo.class); 
    Root<TopUpRAMS> c = data.from(TopUpRAMS.class); 
    data.select(cb.construct(TopUpRAMSInfo.class, 
      c.get("deviceId"), 
      cb.sum(c.get("rechargeValue")) 
     ) 
    ); 
    data.where(cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI), 
     cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF) 
    ); 
    data.groupBy(c.get("deviceId")); 

    TypedQuery<TopUpRAMSInfo> datos = emDAO.createQuery(data); 
    lista = datos.getResultList(); 
    return lista; 
} 
+0

感謝洛斯伊什...... –

+0

不客氣。順便說一句,如果這篇文章回答了你的問題,請接受它。謝謝! – Ish

+0

這工作..只有變化是在創建Crtieria查詢,代碼應該讀爲 CriteriaQuery data = cb.createQuery(TopUpRAMSInfo.class); –

0

Ish回答解決問題。它是類TopUpRAMSInfo上的屬性的類型,它應該是一個int。