2013-03-11 29 views
5

Tôi đang tính toán một SUM nhóm lại theo thángJPA/Hibernate trở BigDecimal không lâu

Query q = entityManager.createNativeQuery(qlString); 
q.setParameter("program", program); 
@SuppressWarnings("unchecked") 
List<Long> resultList = (List<Long>) q.getResultList(); 
long tend = System.currentTimeMillis(); 

Khi tôi vượt qua trong hai resultsLists (đóng cửa: ResultsList các mặt hàng đóng, closedLate: ResultsList các mặt hàng đóng muộn) vào một phương pháp tính tỷ lệ phần trăm, tôi nhận được

javax.servlet.ServletException: java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.Long 

.

private List<Long> computeOTR(List<Long> closed, List<Long> closedLate) { 
    List<Long> monthlyOTR = new ArrayList<Long>(); 
    long numerator; 
    Long denominator; 
    for (int i = 0; i <11; i++) { 
     numerator = closed.get(i) - closedLate.get(i); <----java.lang.ClassCastException 
     denominator = closed.get(i); 
     long percentage = (int)(numerator * 100.0/denominator + 0.5); 
     monthlyOTR.add(i, percentage); 
    } 
    return monthlyOTR; 

}

Trong chế độ debug Eclipse đóng được hiển thị như BigDecimal. Tại sao điều này khi tôi decalre

List<Long> resultList = (List<Long>) q.getResultList();

EDIT-Hibernate Query:

public List<Long> findClosedLateByProgram(String program) { 

    long tstart = System.currentTimeMillis(); 
    //@formatter:off 
    String qlString = "with PRJ as (" + 
      "select trunc(END_DATE) as END_DATE, " + 
      "trunc(NEED_DATE) as NEED_DATE " + 
      "from (SELECT UNIQUE * FROM TEST where PROGRAM_NAME = :program " + 
      "AND ACTION_BY_ORG = 'AAA') " + 
      "), " + 
      "DATES as (select add_months(trunc(last_day(SYSDATE)), level-7) as thedate " + 
      "from dual connect by level <= 12 ) " + 
      "SELECT nvl(sum(case when NEED_DATE < trunc(thedate,'mm') AND END_DATE between trunc(thedate,'mm') and thedate then 1 end), 0) as CLOSED_LATE " + 
      "FROM DATES, PRJ " + 
      "GROUP BY thedate ORDER BY thedate"; 
    //@formatter:on 

    Query q = entityManager.createNativeQuery(qlString); 
    q.setParameter("program", program); 
    // q.setParameter("today",date, TemporalType.DATE); 

    @SuppressWarnings("unchecked") 
    List<Long> resultList = q.getResultList(); 
    long tend = System.currentTimeMillis(); 
    long elapsed = tend-tstart; 
    System.out.println("Elapsed Time For Closed But Late: " + elapsed); 
    return resultList; 
} 

EDIT 2

Tôi nghĩ rằng tôi đang bị mắc kẹt với một BigDecimal? http://weblogs.java.net/blog/mb124283/archive/2007/04/java_persistenc.html

+0

Xem thêm http://stackoverflow.com/questions/3574029/what-does-jpa-entitymanager-getsingleresult-return-for -a-count-query – Vadzim

Trả lời

4

Bạn đã nhận được cảnh báo cho biết dàn diễn viên của bạn không thực sự kiểm tra mọi thứ. Type erasure có nghĩa là tại thời điểm thực hiện, không có sự khác biệt giữa List<Long>List<BigDecimal>. Vì vậy, dàn diễn viên thành công và chỉ ẩn ẩn sau truyền đến Long không thành công.

Về cơ bản, bạn cần phải thay đổi truy vấn của mình để đảm bảo rằng truy vấn đó tạo ra các giá trị Long thay thế.

+0

Tôi hiểu. Danh sách kết quả truy vấn của tôi là [33,23,25,29,15,30, NULL, NULL, NULL, NULL, NULL, NULL] Tôi đoán NULL đang chuyển nó sang BigDecimal. – jeff

+0

@jeff: Không, nó sẽ tùy thuộc vào truy vấn của bạn. Có vẻ như nó nghĩ rằng nó lấy dữ liệu số nguyên. –

+0

Quyền của bạn về điều đó. Tôi chỉ cố định truy vấn của tôi để retun 0 thay vì NULL và Danh sách vẫn là BigDecimal. Truy vấn chỉ đếm Bản ghi để có, chỉ là dữ liệu số nguyên. Nếu tôi loại bỏ tất cả Generics khỏi truy vấn JPA của tôi và sau đó trong chế độ gỡ lỗi inpsect resultsList, nó hiển thị BigDecimal cho giá trị số nguyên 12 của tôi. Tôi không hiểu làm cách nào khác để sửa đổi truy vấn – jeff

0

Bạn nên lặp qua các kết quả và chuyển đổi các đối tượng từ String:

Query query = createSQLQuery(sql); 
    List<Long> ids = new java.util.ArrayList<Long>(); 
    java.util.Iterator res = query.list().iterator(); 

    try { 
     while(res.hasNext()){ 
      ids.add(new Long(res.next().toString())); 
     } 
    } catch(Exception ex) { 
     ex.printStackTrace(); 
    } 
+0

BigDecimal # longValue() – MirandaVeracruzDeLaHoyaCardina

Các vấn đề liên quan