2008-12-15 40 views
26

我試圖做的查詢結果分頁與Hibernate和displaytag和Hibernate DetachedCriteria對象正在盡最大努力在路上的絆腳石。讓我來解釋......如何在Hibernate中重用Criteria對象?

做分頁用displaytag最簡單的方法似乎是實現PaginatedList接口有(其中包括)以下方法:

/* Gets the total number of results. */ 
int getFullListSize(); 

/* Gets the current page of results. */ 
List getList(); 

/* Gets the page size. */ 
int getObjectsPerPage(); 

/* Gets the current page number. */ 
int getPageNumber(); 

/* Get the sorting column and direction */ 
String getSortCriterion(); 
SortOrderEnum getSortDirection(); 

我想扔我PaginatedList的實施標準的對象,讓它沿着theese線工作...

getFullListSize() { 
    criteria.setProjection(Projections.rowCount()); 
    return ((Long) criteria.uniqueResult()).intValue(); 
} 

getList() { 
    if (getSortDirection() == SortOrderEnum.ASCENDING) { 
     criteria.addOrder(Order.asc(getSortCriterion()); 
    } else if (getSortDirection() == SortOrderEnum.DECENDING) { 
     criteria.addOrder(Order.desc(getSortCriterion()); 
    } 
    return criteria.list((getPageNumber() - 1) * getObjectsPerPage(), 
         getObjectsPerPage()); 
} 

但是,這並不工作,因爲addOrder()setProjection()通話修改的標準對象呈現它,我n可用於連續呼叫。我並不完全確定這些調用的順序,但db在嘗試執行「select count(*) ... order by ...」的getFullListSize()時會拋出一個錯誤,這顯然是錯誤的。

我覺得我可以創造我自己的目的是跟蹤的查詢條件和重建對象的標準爲每個呼叫解決這個問題,但感覺就像重新發明另一個輪子。有沒有更聰明的方法,可能會複製最初傳入並處理該副本的標準?

更新: 看起來getList首先調用,getFullListSize之後多次調用,所以,只要有傳入的排序,getFullListSize將失敗。它將使意義擊中分貝只有一次(在getList我說)和緩存結果,而無需複製/重置Criteria對象,但仍...

更新(再次): 忘記的是,一旦我已經做了我count不能做select,反之亦然。我真的需要兩個截然不同的對象。

回答

2

好,DetachedCriteria之後是序列化,所以你有內置的(如不雅)深克隆支持。您可以在構建時將初始條件序列化爲byte [],然後在每次使用時將其反序列化。

+0

發現對hibernate論壇的建議,但我寧願不:-) – agnul 2008-12-16 09:05:37

1

醜陋,因爲它可能是我結束了使用序列化技巧。我只是將DetachedCriteria對象序列化到構造PaginatedList對象的字節數組,並在需要時對其進行反序列化。哎喲。

0

另一件事值得嘗試:

實現一個通用的DAO像the one suggested on hibernate's site,並把它傳遞給PaginatedList對象,以限制對象一起。然後PaginatedList對象會做類似

Criteria.forClass(myDAO.getPersistentClass()) 
     .add(myRestrictions) 
     .addOrder(<someOrder>) 

Criteria.forClass(myDAO.getPersistentClass()) 
     .add(myRestrictions) 
     .setProjection(Projections.rowCount()); 

還沒有嘗試過呢,但它應該工作。

44
Criteria.setProjection(null); 
Criteria.setResultTransformer(Criteria.ROOT_ENTITY); 

將有效地「重置」rowCount投影和標準本身執行之間的標準。

我會確保您的訂單在添加rowCount之前尚未添加,它會減慢速度。我的PaginatedList ALWAYS實現在查找結果之前運行計數查詢,因此排序不是問題。

+5

建議這是正確的答案 - 比深克隆更優雅。 – 2012-03-21 13:48:03

-1
public static DetachedCriteria Clone(this DetachedCriteria criteria) 
{ 
    var dummy = criteria.ToByteArray(); 
    return dummy.FromByteArray<DetachedCriteria>(); 
} 
相關問題