#

Hibernate Deeper OrderBy

Hibernate unterstützt in der Criteria API bei der Angabe von Properties für Criterions oder auch Sortierungen lediglich die Angabe von Properties der Tiefe 1.
Beispielsweise ist criteria.addOrder(Order.asc("id")) möglich, jedoch criteria.addOrder(Order.asc("parent.id")) oder gar criteria.addOrder(Order.asc("parent.parent.id")) nicht möglich.
Um diese Abbilden zu können, muss man sich einiger Joins oder Aliase bedienen.
Im folgenden wird dies anhand der Sortierung gelöst.

Angenommen wir erhalten das Sortierkriterium als String orderBy, welches eine Property oder einen Property-Pfad für das entsprechende Attribut enthält.
So können mit Hilfe eines simplen „Parsers“ die benötigten Aliase für Joins hinzugefügt werden.
Die Hilfsmethode StringUtil.occurences(String s, char c) zählt lediglich die Vorkommen von c in s.
Zusätzlich wird in boolean asc hinterlegt, ob absteigend (true) oder aufsteigend (false) sortiert wird.

final Criteria criteria = getCurrentSession().createCriteria(MyDomain.class, "d");
// d ist alias für unser domain objekt
 
if (orderBy!=null && orderBy.trim().length()>0){
  // erlaubt die benutzung von z. b. d.parent.object.name zum sortieren
  if (StringUtil.occurences(orderBy, '.')>0){
    final String [] parts = orderBy.split("\\.");
    criteria.createAlias("d."+parts[0], "x"+parts[0]);
    for (int t=1; t<=parts.length-2; t++){
      criteria.createAlias("x"+parts[t-1]+"."+parts[t], "x"+parts[t]);
    }
    orderBy = "x"+parts[parts.length-2]+"."+parts[parts.length-1];
  }
  if (asc){
    criteria.addOrder( Order.asc(orderBy) );
  }
  else{
    criteria.addOrder( Order.desc(orderBy) );
  }
}

Der Kode erzeugt Aliase für alle in der orderBy vorkommenden Properties und kann auch verwendet werden, um in Criterions einen entsprechenden Pfad zu bauen.

Leave a Reply »»

Note: All comments are manually approved to avoid spam. So if your comment doesn't appear immediately, that's ok. Have patience, it can take some days until I have the time to approve my comments.