2010-03-03 3 views
5

Ich habe eine Criteria mit:Entfernen dynamisch eine Ordnung auf die Ergebnismenge in org.hibernate.Criteria

Allerdings, wenn ich die rowcount bekommen scheitern:

criteria.setProjection(Projections.rowCount()); 

, weil es ist eine Reihenfolge in der Abfrage.

Wie die Reihenfolge in den Kriterien dynamisch entfernen?

Ich meine, ich suche nach criteria.removeOrder("ID").

+0

Hmm ... warum nennst du 'addOrder()', wenn du es nicht willst? –

+0

@PascalThivent guter Punkt. Manchmal erhalten Sie möglicherweise ein Criteria-Objekt mit einer integrierten Reihenfolge (z. B. von einer Factory-Methode) und möchten diese vordefinierte Reihenfolge möglicherweise entfernen. Deshalb bin ich auf diese Frage gekommen. –

Antwort

5

Es klingt, als ob Sie versuchen, ein Kriterium wiederzuverwenden, das für das Abrufen einer geordneten Liste erstellt wurde, um stattdessen eine Zählung zu erhalten.

Anstatt zu versuchen, dieselben Kriterien zum Abrufen von Daten und zum Zählen zu verwenden, sollten Sie wahrscheinlich am einfachsten unabhängige Kriterien erstellen.

Verwenden

Criteria orderCriteria= session.createCriteria(Libro.class) 
           .addOrder(Order.asc("ID")); 

die Liste in der Reihenfolge abzurufen und

Criteria countCriteria= session.createCriteria(Libro.class) 
           .setProjection(Projections.rowCount()); 

verwenden, um die Zählungen zu erhalten.

Um die gleichen Kriterien für zwei Zwecke zu verwenden, müssen Sie den Status zwischen den Verwendungen ändern. Ich bin mir nicht sicher, wie ich eine Bestellung entfernen soll (oder wenn Sie wirklich müssen, um eine Zählung durchzuführen). Um eine Projektion zu entfernen, benötigen Sie nur setProjection(null).

0

Wenn Sie Kriterien als param erhalten und Sie haben einige Berechnung mit ihm könnten Sie .Clone(), wie hier:

private static int GetTotalRows(ICriteria criteria) 
    { 
     var countCriteria = (ICriteria)criteria.Clone(); 
     return Convert.ToInt32(countCriteria.SetProjection(Projections.RowCount()).UniqueResult()); 
    } 

Andere Lösung ist ClearOrders zu verwenden, die alle Auftragsliste entfernen.

private static int GetTotalRows(ICriteria criteria) 
    { 
     criteria.ClearOrders(); 
     ... 
    } 

Grüße

+0

'criteria.ClearOrders()' ist was ?? –

1

Ich hatte auch das gleiche Problem konfrontiert .. aber ich erreichte in der folgenden Art und Weise,

Vor Auftrag Anwendung i die Anzahl der Datensätze abgefragt,

criteria.addOrder(pageCriteria.isSortDescending() ? Order 
          .desc(pageCriteria.getSortBy()) : Order 
          .asc(pageCriteria.getSortBy())); 

pageCriteria.setTotalRecords(((Integer) criteria 
          .setProjection(Projections.rowCount()) 
          .uniqueResult()).intValue()); 
       criteria.setProjection(null); 
       criteria.setFirstResult(
         pageCriteria.getFirstRecordOfCurrentPage()) 
         .setMaxResults(pageCriteria.getRecordsPerPage()); 
       criteria 
         .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); 

Der obige Code funktioniert gut für mich.

0

Sie können die Reihenfolge nicht nach Kriterien ändern. Meine Lösung für die Paginierung besteht darin, Order [] als Parameter für die Methode zu übergeben, die die Seitennummerierung durchführt.

Sie müssen dies nur tun, wenn db ist db2 as400 oder andere Datenbank, die keine Bestellung von innerhalb select count(*) zulassen.

1

criteria.ClearOrders() ist die Methode NHibernate vorgesehen, um Aufträge zu entfernen.

In Java gibt es keine solche Methode. Und meine Lösung für dieses Problem ist die Verwendung von Order als weiteren Parameter zusammen mit Criteria an die Paginierung Abfrage-Funktion.

6

Die meisten Kriterien sind Instanzen von CriteriaImpl. Wenn Sie Ihre Kriterien in CriteriaImpl umwandeln und den Iterator für Aufträge abrufen, können Sie sie auf diese Weise entfernen.

+0

Gibt es einen Iterator für Projektionen? Ich habe das gleiche Problem und möchte auf meine projectsList zugreifen –