(Spring+Hibernate) Verwendung von HibernateTemplate und persistentes Objekt?

DarthShader

Erfahrenes Mitglied
Hallo,

ich verwende Spring in Kombination mit Hibernate, und die Hilfsklassen, die Spring zur Verfügung stellt, wie z.B. HibernateDaoSupport und HibernateTemplate.

Wenn ich eine ganz einfach DAO verwende, die so aussieht:

Code:
public class HibernateProtocolDaoImpl extends HibernateDaoSupport implements ProtocolDao {
	@Override
	public void saveProtocol( Protocol protocol ) {
		getHibernateTemplate().saveOrUpdate( protocol );
	}
}

dann ist es ja so, das Spring für mich das Öffnen und Schließen der Hibernate Session übernimmt. Bedeutet das aber, dass ich nach dem Aufruf von "getHibernateTemplate().saveOrUpdate" kein persistentes Objekt haben? Denn das hier geht anscheinend nicht:

Code:
public class HibernateProtocolDaoImpl extends HibernateDaoSupport implements ProtocolDao {
	@Override
	public void saveProtocol( Protocol protocol ) {
		getHibernateTemplate().saveOrUpdate( protocol );
		
		protocol.setIrgendwas( true );
	}
}

Das Feld "irgendwas" landet dann nicht in der Datenbank, wird von Hibernate also nicht automatisch aktualisiert, auch nicht wenn ich ein "flush()" mache.

Habe ich es also richtig verstanden, dass mit dem "getHibernateTemplate().saveOrUpdate(..)" nach dem Aufruf die Hibernate Session geschlossen ist, und ich kein persistentes Objekt habe? So müsste ich in vielen Fällen ja auf den Komfort von HibernateTemplate verzichten, um "richtig" mit den Objekten (im Hibernate-Sinne) arbeiten zu können.


Über Eure Hilfe würde ich mich sehr freuen


Vielen Dank!
 
Wie hast du denn die Transaktionen konfiguriert? Gibt es da überhaupt eine drumherum? Normalerweise hat die Session die gleiche Lebensdauer wie die Transaktion. Hast du keine Transaktion wird für jeden direkten Call auf das Template eine Session aufgemacht.

Weiterhin glaube ich, dass du das Persistenzverhalten von Hibernate mit dem von JPA verwechselst. JPA persistiert Änderungen am Objektgraphen beim commit der Transaktion, so dass kein explizites save notwendig ist. Dass Hibernate das auch tut wäre mir neu. Du kommst also um einen zweiten saveOrUpdate Call nit herum.

Warum eigentlich nicht gleich JPA?

Gruß
Ollie
 
Hallo Oliver,

vielen Dank für Deine Antwort. Ich habe noch keine Transaktionen definiert, dies ist auch für meine Frage glaube ich nicht so relevant bzw. ich hätte sagen sollen, dass ich die Frage in Bezug auf das Nichtvorhandensein von Transaktionsdefinitionen beziehe.

JPA ist ja Teil der EJB 3 Spezifikation - Hibernate stellt eine Implementierung der JPA dar. Damit könnte man sagen, dass ich JPA verwende, wenn ich Hibernate verwende - soweit zu meinem bescheidenen Wissensstand ;)

Damit hat sich die Frage, ob Hibernate überhaupt in der Lage ist, solche updates automatisch zu machen, ja fast erledigt. Also Hibernate kann das auf jeden Fall - soweit ich weiß, sind diese Einflüsse sogar von Hibernate nach JPA geflossen.

Wenn ich Spring nicht verwende, dann geht solch ein Arbeiten auf einem persistenten Objekt auf jeden fall. Die DB wird aktualisiert, ohne dass man dies selbst tun müsste.

Ich weiß nur eben nicht genau, wie sich das bei der Verwendung von Springs HibernateTemplate verhält, weil das ja die Session selbstständig öffnet und schließt.
 
Hallo Oliver,

vielen Dank für Deine Antwort. Ich habe noch keine Transaktionen definiert, dies ist auch für meine Frage glaube ich nicht so relevant bzw. ich hätte sagen sollen, dass ich die Frage in Bezug auf das Nichtvorhandensein von Transaktionsdefinitionen beziehe.
Ohne Transaktion ist nach dem Call die Session weg. Nachzuschauen im HibernateTemplate, Methode doExecute(HibernateCallback, boolean , boolean). Da ist im finally Block explizit die Unterscheidung drin.

JPA ist ja Teil der EJB 3 Spezifikation - Hibernate stellt eine Implementierung der JPA dar. Damit könnte man sagen, dass ich JPA verwende, wenn ich Hibernate verwende - soweit zu meinem bescheidenen Wissensstand ;)
Das ist falsch. JPA ist ein API. D.h. solang du nicht gegen die JPA programmierst, nutzt du sie nicht ;). Nimmt man nun diesen Fakt als gegeben hin, stellt sich die Frage ob Hibernate diese API implementiert. Hibernate Core (so wie du ihn z.B. benutzt) tut dies explizit *nicht*. Allerdings gibt es aus dem Hibernateprojekt eine Implementierung der JPA, die unter der Haube den Hibernate Core implementiert. Das ist ein wichtiger Unterschied.

Damit hat sich die Frage, ob Hibernate überhaupt in der Lage ist, solche updates automatisch zu machen, ja fast erledigt. Also Hibernate kann das auf jeden Fall - soweit ich weiß, sind diese Einflüsse sogar von Hibernate nach JPA geflossen.

Wenn ich Spring nicht verwende, dann geht solch ein Arbeiten auf einem persistenten Objekt auf jeden fall. Die DB wird aktualisiert, ohne dass man dies selbst tun müsste.
So genau steck ich da nicht drin, aber mit der geschlossenen Session ist halt eben essig. Ein Persistenzkontext ist in der Hibernateimplementierung der JPA über die Session abgebildet, d.h. dieser Autopersistiermechanismus funktioniert nur innerhalb einer offenen Session.

Ich weiß nur eben nicht genau, wie sich das bei der Verwendung von Springs HibernateTemplate verhält, weil das ja die Session selbstständig öffnet und schließt.
Siehe oben. Nur keine Angst vor dem Sourcecode. Der ist bei Spring in großen Teilen sehr verständlich :).
 
Hallo Oliver,

danke für Deine ausführliche Antwort und die "Hintergrundinformationen" zu Hibernate und JPA. Ich sollte vielleicht einfach den Nutzen von HibernateTemplate in meinem Code etwas hinterfragen - auch den Sourcecode von Spring schaue ich mir einmal an, danke!
 
Kein Thema :). Wie gesagt, wenn du irgendne Möglichkeit hast, deine DAOs direkt gegen JPA zu programmieren, ist das das einfacherere und sauberere Programmiermodell. Zudem gibt es aufbauen auf Spring und JPA eine nützliche Library (http://hades.synyx.org - shameless plug ;)) die hilft, Datenzugriffscode auf ein minimum zu reduzieren. Grundsätzlich lässt sich sagen, dass JPA wohl "the way to go" ist.

Gruß
Ollie
 
Hm ok - ich hoffe nur nicht, dass ich jetzt eine falsche Architekturentscheidung getroffen habe. Generell ist es so, dass ich mein Domain Modell komplett mit Annotationen der JPA konfiguriert habe. Das ist ja nicht Hibernate-Spezifisch. Als müsste es ja theoretisch möglich sein, mit nicht all zu großem Aufwand zu JPA zu wechseln.

Ich war bisher immer sehr von Hibernate angetan, sehr mächtig mit guten Tools. Direktes JPA, auch in Verbindung mit dem von Dir genannten Framework, werde ich mir mal anschauen.

Ich scheue mich immer etwas davor, solche kleinen Framework zu verwenden - ist das Major? Wird es noch lange supported? Stehe ich bei einem Problem irgendwann alleine da? :) Bei Hibernate sind die Antworten klar.
 
Hallo Oliver,

wenn ich nocheinmal nachfragen darf, welche Implementierung der JPA würdest Du empfehlen? Momentan habe ich einen Server, der lediglich in Spring und Hibernate umgesetzt ist, also ohne Servlet Container bzw. Application Server.
 
Hm ok - ich hoffe nur nicht, dass ich jetzt eine falsche Architekturentscheidung getroffen habe. Generell ist es so, dass ich mein Domain Modell komplett mit Annotationen der JPA konfiguriert habe. Das ist ja nicht Hibernate-Spezifisch. Als müsste es ja theoretisch möglich sein, mit nicht all zu großem Aufwand zu JPA zu wechseln.

Du hast keine falsche Architekturentscheidung getroffen, sonder eine vielleicht suboptimale Technologieentscheidung. Anders rum wäre die Sache vermutlich problematischer. Du hast einen DAO Layer, d.h. eine Implementierung bereitzustellen, die jetzt auf JPA aufsetzt sollte nicht das Problem sein. Es gibt für JPA ähnlich wie für Hibernate ein Template, dass man allerdings eigentlich nicht braucht. Du kannst im Allgemeinen direkt @EntityManager in den DAOs benutzen.

Ich scheue mich immer etwas davor, solche kleinen Framework zu verwenden - ist das Major? Wird es noch lange supported? Stehe ich bei einem Problem irgendwann alleine da? :) Bei Hibernate sind die Antworten klar.
In dem Fall fragst du den Falschen, weil ich quasi Autor der Bibliothek bin. Der Grund dieses Ding anzufangen war für mich, dass man viele grundsätzliche Dinge die Persistenz angehen eh in jedem Projekt wieder codet bzw. es jede Menge Best Practices gibt, für die es noch keine OpenSource Implementierung gab.

Das Ding macht eigentlich 4 Dinge: es implementiert oben verlinkten Artikel, was dazu führt, dass du für Standard CRUD Operationen ein generisches DAO bekommst, dass du nur für alle Entitäten nutzen kannst (1 DAO pro Entität, streng typisiertes Interface im Gegensatz zum EntityManager). Zweitens gibt es jede Menge Hilfsklassen für Entitäten, Hilfestellung bei Pagination (Verteilen von Anfrageergebnissen auf Seiten usw.). Der 3. Punkt ist das Ausführen von Queries durch einfaches Deklarieren von Methoden in Interfaces. Keine weitere Implementierung notwendig. Darüber hinaus gibt es noch eine Reihen von Supportfeatures, wie transparentes Auditing, ein Spring Namespace usw. Wichtig hierbei ist, dass du das ganze der Tradition von Spring folgend selektiv nutzen kannst, also immer nur das, was man wirklich braucht.

Schau dir mal die Beispielapplikation an, die gibt nen guten Überblick über die möglichen Tiefen der Nutzung. Spannend hierbei ist auch, dass es möglich ist sich in einen bestehenden Data Access Layer basierend auf Hibernate reinzuhängen und z.B. zu Test- und Experimentierzwecken mal einzelne DAOs mit Hades zu bauen und dabei den Rest auf plain Hibernate zu lassen usw. Details, wie man das konfiguriert gibt es in der Referenzdoku im FAQ Teil.

Gruß
Ollie

PS: generell empfehle ich Hibernate... OpenJPA ist halt nach der JPA Schluss und es gibt einige Stellen, an denen man beim Mapping schon mal auf proprietäre Annotations zurückgreifen muss. Das geht dann halt nur mit Hibernate und Toplink. Hibernate arbeitet ja mit Bytecodeenhancement (cglib), Toplink setzt auf Loadtimeweaving (aop). Ich persönlich bevorzuge daher Hibernate, da das weniger Implikationen auf den Betrieb hat. Desweiteren gibt es bei Toplink noch hier und da ein paar quirks, die relativ hässlich sind...
 
Hi,

In dem Fall fragst du den Falschen, weil ich quasi Autor der Bibliothek bin.

jetzt verstehe ich auch den Smiley da oben neben dem Hades-Link ;) Der Untertitel des Artikels den Du erwähnst, lautet "Build a generic typesafe DAO with Hibernate and Spring AOP". Kann man mit Deinem Hades auch in bezug auf Spring und Hibernate etwas anfangen, oder werde ich nur glücklich, wenn ich ne reine JPA Implementation und Dein Hades verwende?

Ich weiß nicht, ob ich JPA schon richtig verstehe - es gibt da also mehrere Implementierungen? Auch welche, die nicht im Rahmen eines Applikations-Servers laufen?


Mal ganz am Rande: ich interessiere mich sehr für die Enterprise Entwicklung mit Java. Allerdings muss ich immer wieder feststellen, wieviele Technologien, Best Practices, Architekturen etc. es noch zu lernen gibt. Ich versuche mein Möglichstes, ständig auf dem Laufenden zu sein und stets dazu zu lernen. Leicht ist es nicht, da mitzuhalten :) Deshalb bitte ich sehr dankbar über solche Threads, in denen es um Vorgehensweisen und allgemeine Technologien geht.
 

Neue Beiträge

Zurück