Hibernate ORM 6 – Hibernate Query Language (HQL)

Hibernate ist – wie viele andere Frameworks auch – bekannt dafür, dass die automatisch erzeugten Queries unnötig komplex und leider oft auch ineffizient sind. Schon in älteren Versionen von Hibernate konnten Entwickler Native SQL nutzen, um manuell Optimierungen vorzunehmen.

Hier einige Links zu Beispielen wie das funktioniert:

Dies ist aber mit den aktuellen Verbesserungen der Hibernate Query Language meist nicht mehr nötig, da HQL im Laufe der Zeit um viele SQL Funktionen erweitert wurde. Der Vorteil der Nutzung von HQL gegenüber den Native SQL Queries ist der Vorteil, dass die HQL den Code für verschiedene Datenbanken wie Oracle, PostgreSQL, DB2 und anderen Datenbanken entsprechend erzeugen kann. Damit wird auch der Umstieg von einer Datenbank auf eine andere erleichtert.

Was bietet die HQL 6.4 an interessanten SQL Features

Unterstützung von SQL Window-Functions

Window-Funktionen in SQL ermöglichen auf Teilbereiche der Ergebnismenge Operationen durchzuführen. Im folgenden Beispiel wird die Anzahl der bestellten Güter über die Zeit summiert (HQL Syntax):

select item.order.dateTime,
       sum(item.quantity) 
          over (order by item.order.dateTime) 
          as runningTotal
from Item item

Unterstützung von „userdefined“ Spaltentypen

Datenbanken wir Oracle bieten schon seit langem „userdefined“ Datentypen an. Diese werden auch oft für JSON bzw XML Typen benötigt. Hier ein Beispiel (Oracle Datenbank):

create type person 
  as (firstname varchar2(32),
      lastname varchar2(32));

create table mitarbeiter (
  id number primary key,
  Name person);

Dies kann man jetzt direkt als Record in Hibernate implementieren.

@Embeddable
@Struct(name = "person")
public class myPerson {

  private String firstname;
  private String lastname;

  ...
}

Empfehlung (zumindest bei Oracle Datenbanken): Man kann das ganze auch so implementieren, dass die Tabellen ohne userdefined Datentype angelegt werden und das ganze mittels einer (Object) View gemapped wird. Der Vorteil ist, dass Änderungen an relationalen Tabellen einfacher umzusetzen sind, wie Änderung an userdefined Datentypen.

Nutzung von Zeitzonen

Beginnend mit HQL 6 kann man den TimezoneStorageType angeben und ab 6.2 auch in der Konfiguration hibernate.timezone.default_storage voreinstellen.

@Entity
public class MyEntity {
    
  @TimeZoneStorage(TimeZoneStorageType.DEFAULT)
  private ZonedDateTime zonedDateTime;

  ...
}

Damit erleichtert man den Umgang mit dem Datentype TIMESTAMP WITH TIMEZONE in den verschiedenen Datenbanken.

Zusammenfassung

Durch die laufenden Erweiterungen von HQL gibt es langsam aber sicher keine Ausrede mehr für Entwickler, dass man bei suboptimalen automatisch generierten Statements (durch Hibernate Framework) nichts machen kann, weil es ja immer so umständlich und proprietär (Native SQL) umzusetzen ist. Inzwischen ist es mit HQL fast immer möglich einfachere und schnellere SQL Statements generieren zu lassen, als das Framework von sich aus erzeugt.

Weitere Informationen

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

This site uses Akismet to reduce spam. Learn how your comment data is processed.