HTTP-Requests, Hibernate Sessions und ThreadLocal
Kurz zum Hintergrund:
Hibernate kapselt Datenbank-Persistenz von der Anwendungslogik. Somit sind keine Low-Level-Datenbankoperationen mehr nötig, die entsprechenden SQL-Statements werden von Hibernate erzeugt. Im Hintergrund öffnet Hibernate die Verbindung zur DB, schickt Statements und stößt die Ausführung an (commit), dies alles im Kontext einer „Session“. Die Erzeugung einer Session ist keine teuere Operation, es wird in der Hibernate-Literatur empfohlen, möglichst kurze Sessions zu verwenden und bei Bedarf neue zu erzeugen.
In der ersten Implementierung der Veranstaltungsverwaltung gab es (sehr schlecht!!) nur eine Session pro Sitzung, d.h. beim Login wurde eine Session erzeugt, die erst bei der Abmeldung wieder freigegeben wurde. Um das Session-Objekt von den Objekten anderer angemeldeter Teilnehmer abzuschotten, wurde es als ThreadLocal an den aktuellen Thread gebunden. Folge war, dass in bestimmten Konstellationen Domänenobjekte veraltete Daten gespeichert hatten, denn ein neuer Request eines Browsers kann in einem anderen Thread abgesetzt werden als bisher.
Inzwischen ist ein Session-Per-Request implementiert, das heißt, dass für jeden Aufruf einer Seite eine neue Session erzeugt wird, die nach erfolgreichem Laden committed und beendet wird. Dies hat jedoch Auswirkungen:
- Änderungen an der Datenbank (Update, Insert) werden erst ausgeführt, nachdem ein commit() auf die Transaktion der Session aufgerufen wurde. Bei Session-Per-Request kommt dieses commit eigentlich zu spät, nämlich erst nach der Darstellung des Inhalts der Seite. Daher muss das commit() bei Änderungsaktionen explizit angestoßen werden.
- Objekte, die nicht an eine Session gebunden sind, verursachen Fehler, sobald sie auf ihre Felder zugreifen wollen (Hibernates Lazy Loading – DB-Aktionen werden erst ausgeführt, wenn das Objekt tatsächlich benötigt wird, an sich eine gute Sache) oder selbst wieder persistiert werden sollen („Hibernate: no session or session was closed“). Auch auf solche Fälle muss daher in Zukunft sorgfältig geachtet werden.