Question

Je suis en train de faire Pagination de résultat de requête avec mise en veille prolongée et displaytag et Hibernate objets font DetachedCriteria leur mieux pour barrer la route. Laissez-moi vous expliquer ...

La meilleure façon de le faire avec displaytag semble pagination à mettre en œuvre l'interface qui a PaginatedList, entre autres, les méthodes suivantes:

/* 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();

Je pense à lancer ma mise en œuvre de PaginatedList un objet Criteria et le laisser travailler le long theese lignes ...

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());
}

Mais cela ne fonctionne pas, parce que le ou les addOrder() modifient les appels setProjection() critères objet rendant en utilisable pour les appels successifs. Je ne suis pas tout à fait sûr de l'ordre des appels, mais le db génère une erreur sur essayer de faire getFullListSize() un « select count(*) ... order by ... » qui est évidemment faux.

Je pense que je pourrais résoudre ce problème en créant un objet de mon propre à garder une trace des conditions de la requête et la reconstruction de l'objet Critères pour chaque appel, mais qui se sent comme réinvente encore une autre roue. Y at-il une façon plus intelligente, peut-être copier les critères initialement transmis et de travail sur cette copie?

Mise à jour : On dirait que la première est appelée getList, et est appelée plusieurs getFullListSize fois après, donc, dès qu'il ya un ordre transmis, échouera Criteria. Il serait logique de frapper le db qu'une seule fois (en count je dirais) et mettre en cache les résultats, sans avoir besoin de copier / réinitialiser l'objet select, mais quand même ...

Mise à jour (nouveau) : Oubliez que, une fois que je l'ai fait le <=> je ne peux pas faire la <=>, et vice versa. J'ai vraiment besoin de deux objets distincts <=>.

Était-ce utile?

La solution

bien, DetachedCriteria sont Serializable, vous avez donc le soutien clone profond intégré (si inélégant). Vous pouvez sérialiser les critères initiaux d'un octet [] une fois sur la construction, désérialiser alors chaque fois que vous voulez utiliser.

Autres conseils

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

Est-ce que « reset » efficacement les critères entre la projection rowCount et l'exécution des critères lui-même.

Je veillerais votre commande n'a pas été ajouté avant de faire le rowCount, ça va ralentir les choses. Ma mise en œuvre de PaginatedList exécute toujours une requête de comptage avant de rechercher des résultats, si la commande est pas un problème.

http://weblogs.asp.net/stefansedich/archive/2008/10/03/paging-with-nhibernate-using-a-custom-extension-method-to-make -it-easier.aspx

Dans ce post, je remarquai une méthode CriteriaTransformer.clone.

Cela devrait copier l'objet de critères.

Vous pouvez également définir la projection sur votre méthode de GetList.

Woops Je n'ai pas remarqué que vous parliez de mise en veille prolongée java. Quoi qu'il en soit, cette http://forum.hibernate.org/viewtopic.php?t=939039

post sur le forum

devrait être en mesure de répondre à votre question.

laid comme il peut être que je fini par utiliser l'astuce de sérialisation. Je viens sérialiser l'objet d'un DetachedCriteria tableau d'octets sur la construction de l'objet et de PaginatedList-sérialiser en cas de besoin. Aïe.

Une autre chose que la peine d'essayer:

mettre en œuvre un générique comme celui proposé sur le site de mise en veille prolongée et le transmettre à la PaginatedList objet, ainsi que d'un objet de restrictions. L'objet PaginatedList serait alors faire quelque chose comme

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

et

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

N'a pas essayé encore, mais il devrait fonctionner.

public static DetachedCriteria Clone(this DetachedCriteria criteria)
{
   var dummy = criteria.ToByteArray();
   return dummy.FromByteArray<DetachedCriteria>();
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top