Frage

Ich versuche, Abfrageergebnis Paginierung mit Hibernate und displaytag zu tun, und Hibernate DetachedCriteria Objekte ihr Bestes im Weg zu stehen tun. Lassen Sie mich erklären ...

Der einfachste Weg, Paginierung mit displaytag zu tun scheint die PaginatedList Schnittstelle zu implementieren, unter anderem hat die folgenden Methoden:

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

Ich denke, meine PaginatedList Implementierung eines Criteria Objekt zu werfen und lassen Sie es entlang ond Linien arbeiten ...

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

Aber das funktioniert nicht, weil der addOrder() oder die setProjection() Anrufe ändern die Kriterien, Objekt-Rendering es in verwendbar für die aufeinanderfolgenden Anrufe. Ich bin nicht ganz sicher, ob die Reihenfolge der Anrufe, aber die db wirft einen Fehler auf getFullListSize() versucht, ein „select count(*) ... order by ...“ zu tun, was offensichtlich falsch ist.

Ich glaube, ich könnte dieses Problem beheben, indem ein Objekt meiner eigenen Schaffung Spur von Abfragebedingungen zu halten und für jeden Anruf die Kriterien Objekt Wiederaufbau, aber das fühlt sich an wie ein weiteres Rad neu zu erfinden. Gibt es eine intelligentere Art und Weise, die möglicherweise das Kopieren die Kriterien zunächst übergeben und die Arbeit an dieser Kopie?

Update : Es sieht aus wie getList zuerst genannt wird, und getFullListSize wird mehrmals nach, so, sobald es eine Bestellung übergeben, getFullListSize fehl genannt. Es wäre sinnvoll, die db zu treffen nur einmal (in getList würde ich sagen) und die Ergebnisse zwischenzuspeichern, ohne die Notwendigkeit zu kopieren / Zurücksetzen des Criteria Objekt, aber immer noch ...

Update (wieder) : Vergessen Sie, dass, sobald ich den count getan habe ich nicht den select tun kann, und umgekehrt. Ich brauche wirklich zwei verschiedene Criteria Objekte.

War es hilfreich?

Lösung

gut, DetachedCriteria sind Serializable, so Sie haben eingebaute (wenn unelegant) tief Klon-Unterstützung. Sie könnten die ersten Kriterien zu einem byte [] einmal auf dem Bau serialisiert, es dann Deserialisieren jedes Mal, wenn Sie wollen, es zu benutzen.

Andere Tipps

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

Wird „Reset“ die Kriterien effektiv zwischen der rowCount Projektion und Ausführung der Kriterien selbst.

Ich würde sicherstellen, dass Ihre Bestellung vor dem rowCount tut nicht hinzugefügt wurde, wird es Dinge verlangsamen. Meine Implementierung von PaginatedList läuft immer eine Zählung Abfrage, bevor sie für Ergebnisse suchen, so Ordnung ist kein Thema.

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

In diesem Beitrag habe ich eine CriteriaTransformer.clone Methode entdeckt.

Das sollte die Kriterien Objekt kopieren.

Sie können auch die Projektion auf Ihrem getlist Verfahren eingestellt.

Woops Ich habe nicht bemerkt, Sie Java Hibernate bezogen sich. Wie auch immer, diese http://forum.hibernate.org/viewtopic.php?t=939039

Forenbeitrag sollte in der Lage sein, Ihre Frage zu beantworten.

hässlich es auch sein mag ich am Ende mit der Serialisierung Trick. Ich serialisiert nur das DetachedCriteria Objekt zu einem Byte-Array auf dem Bau des PaginatedList Objekts und de-serialisiert es bei Bedarf. Ouch.

Eine andere Sache, einen Versuch wert:

implementieren eine generische DAO wie das auf Hibernate Website vorgeschlagen und gibt es an den PaginatedList Objekt, zusammen mit einem Objekt Einschränkungen. Das PaginatedList Objekt würde dann so etwas wie

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

und

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

Haben Sie nicht versucht, dass noch nicht, aber es sollte funktionieren.

public static DetachedCriteria Clone(this DetachedCriteria criteria)
{
   var dummy = criteria.ToByteArray();
   return dummy.FromByteArray<DetachedCriteria>();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top