~/home of geeks

Hibernate Deeper OrderBy

· 203 Wörter · 1 Minute(n) Lesedauer

hall full of ice figures, sci-fi

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 mithilfe 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.