2010-01-29 13 views
20

Ho una combinazione di criteri di ricerca implementati utilizzando criteri di ibernazione. E ho aggiunto un impaginazione come questo:conteggio (*) nei criteri di ibernazione?

criteria.setFirstResult(offset).setMaxResults(pageSize).setFetchSize(pageSize).list(); 

questo non è sufficiente per un'impaginazione, così ho contare la dimensione totale risultato.

totalResult = (Integer)criteria.setProjection(Projections.rowCount()).uniqueResult(); 

Il problema è che la prima volta che invio il modulo di ricerca, ho ottenuto TotalResult corretto. Quando faccio clic sulla pagina successiva e l'offset cambia, ho ottenuto una NullPointExcetion alla seconda istruzione. Non so perché. E attraverso il debug, posso vedere quando si verifica questa eccezione, la prima dichiarazione restituisce correttamente i risultati impaginati.

Quindi voglio chiedere, la prima affermazione è in conflitto con la seconda? (poiché la prima istruzione imposta il valore fetch su 10 e mi chiedo se la funzione count (*) funzionerà correttamente. sono task diversi con gli stessi criteri, Come posso clonare o copiare un criterio che ha già numerose restrizioni?)

risposta

7

Penso che il conflitto sia in realtà la restrizione nella query di conteggio, quindi mi aspetto che restituisca risultati errati nella seconda esecuzione della query di impaginazione.

utilizzando un singolo per i lavoratori richiede un po 'di ripristino tra usi, che probabilmente può essere fatto lungo le linee di:

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

Se si vuole veramente due criteri distinti ma identici, penso che il modo più semplice è quello di per prima cosa create una DetachedCriteria, che è serializzabile, e usate l'hack per la clonazione con serializzazione e deserializzazione per crearne un'altra, prima di convertirli in normali Criteri allegandovi ad una sessione.

Ma se è possibile eseguire un ripristino, potrebbero non essere necessari due.

+0

Grazie, in realtà la mia soluzione è esattamente lo stesso con le vostre risposte. Funziona ! – Sawyer

28

Tanto per fissare numero di query (*) - meglio utilizzare questo codice per criteri:

Integer totalResult = ((Number)criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue(); 

altrimenti si otterrà un errore java.lang.Long cannot be cast to java.lang.Integer

+6

Bel modo senza cast: 'Integer totalCount = criteria.setProjection (Projections.rowCount()). UniqueResult(). HashCode();'. Avrai lo stesso risultato. –

+0

trucco pulito! non me ne sono reso conto fino a quando non ti ho visto commentare e guardare il codice sorgente jdk. – Yogi

+0

Non sono sicuro di fidarmi del tuo trucco (anche se sono impressionato). Il contratto hashCode() dice che il codice hash non deve rimanere lo stesso da una corsa all'altra, quindi Oracle è totalmente nei suoi diritti di cambiare il metodo hashCode(), anche se non è molto probabile. Comunque, preferirei semplicemente chiamare intValue(). – MiguelMunoz

Problemi correlati