Hibernate

Andre Schemschat

Hibernate ist ein Framework für Java und .Net, dass die Benutzung einer Datenbank kapselt und abstrahiert. Die unten stehende Abbildung verdeutlicht dessen Aufbau. An unterster Stelle steht hierbei die Datenbank. Der Zugriff auf diese wird dabei durch die drei Standard-APIs Java Naming and Directory Interface (JDNI), Java Transaction API (JTA) und Java Database Connectivity (JDBC) geregelt. Hibernate setzt auf diese APIs auf, so dass der Zugriff von der spezifischen Struktur abstrahiert werden kann. Die meisten Datenbankhersteller bieten ihre eigenen Implementationen für diese Interfaces an, so dass das Framework unabhängig von der benutzten Datenbank ist.

Abb. 1: Übersicht der Hibernate-Architektur

Auf die JDBC-Schnittstellen setzt dann ein ConnectionProvider auf. Dieser verwaltet die Verbindungen zu der Datenbank über einen ConnectionPool. Aus diesem Pool werden bei neuen Anfragen die offenen Verbindungen entnommen oder neue angelegt, falls keine verfügbar sind. Der Provider ist außerdem dafür verantwortlich nicht mehr benötigte Verbindungen wieder freizugeben. Neben dem ConnectionProvider arbeitet die TransactionFactory. Gerade in größeren Applikationen, in denen zu einer Anfrage mehrere zusammenhängende Datenbankquerys erforderlich sind, bietet es sich an dem ACID-Prinzip zu folgen. Um dies einfach umzusetzen bietet Hibernate mit der Factory eine Möglichkeit, Transaktionen einfach und sicher zu verwalten. Um beide Interfaces in der Applikation komfortabel zu nutzen hat Hibernate eine weitere Abstraktionsebene, die SessionFactory eingefügt. Je nach Kontext der Nutzung stellt diese Klasse automatisch eine Transaktion auf einer offenen Verbindung bereit, ohne dass dies explizit angefordert wird. Ein Kontext kann dabei eine gesamte Applikation, aber auch ein einzelner Thread sein. Gerade letzteres ist bei einem One-Thread-per-Request-Model sehr nützlich, da pro Thread eine neue, atomare Session geöffnet wird.

Die so geöffnete Session ist das Objekt, mit dem innerhalb der Geschäftslogik gearbeitet werden kann. Mit diesem lassen sich Anfragen auf das Model ausführen. Dieses besteht dabei aus Java-Beans (oder POJOs), die über XML-Mappings oder Annotations auf ein relationales Schema überführt werden (Ein detaillierteres Beispiel wird unter Beans vorgestellt). Hibernate agiert hier also auch als Object-relational Mapper. Mit Hilfe der Session und den Beans können dann Anfragen an die Datenbank gestellt werden. Dies geschieht zum einen mit der Hibernate Query Language (HQL). Diese Sprache ist ein Dialekt der Structured Query Language, die auf die objektorientierte Basis angepasst wurde. Die zweite Möglichkeit ist die Criteria-API. Mit dieser lassen sich Schritt für Schritt Ergebnismengen einengen und Queries mit vordefinierten Methoden erstellen. Für beides ist im Folgenden ein kurzes Beispiel gegeben.

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
 
Person aPerson = (Person) session
    .createQuery("select p from Person p left join fetch p.events where p.id = :id")
    .setParameter("id", 5)
    .uniqueResult();
 
...
session.getTransaction().commit();
Eine Anfrage mit HQL
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
 
List<Person> list = (List<Person>)session
     .createCriteria(Person.class)
     .addRestriction(Restrictions.eq("name", "Mustermann"))
     .list();
 
...
session.getTransaction().commit();
Eine Anfrage mit der Criteria-API

Die so geladenen Daten sind als persistente Objekte in der Session verankert. Solange ein Objekt an eine Session attached ist, werden Änderungen automatisch in die Datenbank übernommen, sobald die Transaktion beendet wird. Gleichzeitig ist Hibernate auch in der Lage durch optimistisches oder pessimistisches Locking Dateninkonsistenzen zu vermeiden oder Referenzen dynamisch bei Bedarf nachzuladen.

Neben diesen Kernfeatures bietet das Hibernateframework eine sehr flexible Architektur. So lassen sich weitere Caching-Mechanismen einbinden oder der Connectionpool auswechseln, um nur zwei Beispiele zu nennen.


Page last modified on March 21, 2011, at 09:30 AM