2010-01-29 7 views
20

J'ai une combinaison de critères de recherche implémentés en utilisant les critères de mise en veille prolongée. Et j'ai ajouté une mise en page comme ceci:count (*) dans les critères d'hibernation?

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

Cela ne suffit pas pour une mise en page, donc je compte la taille totale de résultat.

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

Le problème est, la première fois que je soumets le formulaire de recherche, je me suis totalResult correcte. Lorsque je clique sur la page suivante, et que le décalage change, j'ai une NullPointExcetion à la deuxième déclaration. Je ne sais pas pourquoi. Et grâce au débogage, je peux voir quand cette exception se produit, la première déclaration renvoie avec succès les résultats paginés.

Donc, je veux demander, la première déclaration est-elle en conflit avec la seconde? (parce que la première instruction a mis le fetchsize à 10, et je me demande si la fonction count (*) fonctionnera correctement ils sont tâche différente utilisant les mêmes critères, Comment puis-je cloner ou copier un critère qui a déjà de nombreuses restrictions ont été ajoutées?

Répondre

7

Je pense que le conflit est en fait la restriction dans la requête de comptage, donc je m'attends à ce qu'il renvoie des résultats erronés sur la deuxième exécution de la requête de pagination.

L'utilisation d'un seul critère pour les deux nécessite une remise à zéro entre les utilisations, ce qui peut probablement être fait le long des lignes de:

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

Si vous voulez vraiment deux critères distincts mais identiques, je pense que la meilleure façon est de Créez d'abord un DetachedCriteria, qui est Serializable, et utilisez le hack de clonage serialization-deserialization pour en créer un autre, avant de les convertir en Criteria normal en attachant à une session. Mais si vous pouvez travailler sur une réinitialisation, vous n'aurez peut-être pas besoin de deux.

+0

Merci, en fait ma solution est exactement la même chose avec vos réponses. Ça marche ! – Sawyer

28

Juste pour fixer count (*) requête - mieux utiliser ce code pour les critères:

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

sinon vous obtiendrez une erreur java.lang.Long cannot be cast to java.lang.Integer

+6

Belle façon sans incantation: 'Integer totalCount = criteria.setProjection (Projections.rowCount()). UniqueResult(). HashCode();'. Vous aurez le même résultat. –

+0

astuce! n'a pas réalisé cela jusqu'à ce que je vous ai vu commenter et regardé et code source jdk. – Yogi

+0

Je ne suis pas sûr que je fais confiance à votre tour bien (même si je suis impressionné). Le contrat hashCode() indique que le code de hachage ne doit pas rester le même d'un passage à l'autre, donc Oracle est totalement dans son droit de changer la méthode hashCode(), bien que ce ne soit pas très probable. Cependant, je préfère appeler intValue(). – MiguelMunoz

Questions connexes