2010-01-29 24 views
20

Tengo una combinación de criterios de búsqueda que se implementó mediante el uso de criterios de hibernación. Y añadí una paginación de la siguiente manera:recuento (*) en criterios de hibernación?

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

esto no es suficiente para una paginación, así que tengo contar el tamaño total del resultado.

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

El problema es que, la primera vez que envío el formulario de búsqueda, obtuve el totalResult correcto. Cuando hago clic en la página siguiente y el desplazamiento cambia, obtengo una NullPointExcetion en la segunda instrucción. No sé por qué. Y a través de la depuración, puedo ver cuándo se produce esta excepción, la primera declaración devuelve con éxito los resultados paginados.

Así que quiero preguntar, ¿la primera declaración entra en conflicto con la segunda? (porque la primera declaración establece fetchsize en 10, y me pregunto si la función count (*) funcionará correctamente. son tareas diferentes con los mismos criterios, ¿cómo puedo clonar o copiar un criterio que ya tiene numerosas restricciones agregadas?)

Respuesta

7

Creo que el conflicto es realmente la restricción en la consulta de recuento, por lo que esperaría que arrojara resultados incorrectos en la segunda ejecución de la consulta de paginación.

utilizando un único Criterios para tanto requiere un poco de puesta a cero entre usos, lo que probablemente se puede hacer a lo largo de las líneas de:

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

Si realmente quiere dos criterios separados pero idénticos, creo que la forma más fácil es primero cree un DetachedCriteria, que es Serializable, y use el hack de clonación de serialización-deserialización para crear otro, antes de convertirlos a Criteria normal adjuntando a una sesión.

Pero si puede trabajar en un restablecimiento, es posible que no necesite dos.

+0

Gracias, en realidad mi solución es exactamente lo mismo con sus respuestas. Funciona ! – Sawyer

28

Sólo para fijar el recuento de consulta (*) - utilizar mejor el código de criterios:

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

de lo contrario obtendrá un error java.lang.Long cannot be cast to java.lang.Integer

+6

Buena forma sin conversión: 'Entero totalCount = criteria.setProjection (Projections.rowCount()). UniqueResult(). HashCode();'. Tendrás el mismo resultado. –

+0

buen truco! no me di cuenta de esto hasta que te vi comentar y buscar y jdk código fuente. – Yogi

+0

No estoy seguro de que confíe en su astuto truco (aunque estoy impresionado). El contrato hashCode() dice que el código hash no necesita ser el mismo de una ejecución a la siguiente, por lo que Oracle está totalmente dentro de sus derechos para cambiar el método hashCode(), aunque no es muy probable. Aún así, prefiero simplemente llamar a intValue(). – MiguelMunoz

Cuestiones relacionadas