-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 
Author Message
 Post subject: Gutes Design Pattern für Hibernate in Verbindung mit Struts
PostPosted: Tue May 31, 2005 8:24 am 
Regular
Regular

Joined: Sun Aug 01, 2004 6:49 pm
Posts: 76
Hallo,

ich suche nach einem guten (dem ultimativen) Design Pattern für eine Hibernateintegration in Struts. Ich bin bisher immer folgendem Beispiel gefolgt: http://www.hibernate.org/238.html und frage mich nun ob das mit Hibernate 3.xx besser/einfacher geht?

Habt Ihr ein paar aktuelle Beispiele zur Hand? Insbesondere die Frage der Verantwortlichkeit des Haltens und Erzeugens der Session selbst. Wann sollte ein Action eine Session generieren und welchen Lebenszyklus hat eine Session (bis in den View hinein)? Bisher habe ich vor jedem Actionaufruf eine Session erzeugt und diese der Action übergeben um dann auf die Objekte und die Logik zuzugreifen (siehe Link oben). Für den View habe ich diese Daten dann aus den Session-Behafteten Objekte umgewandelt.

Folgendes Kriterium sollte die Integration unbedingt erfüllen:
Keine notwendige Anpassung der Standardkonfiguration des J2EE-Containers (Nutzungsmöglichkeit der Anwendung als Deployable Archiv). Bei den obigen Links gab es unter anderem den Kommentar, dass JNDI bei Tomcat standardmäßig nur lesend benutzt werden kann?!

Besten Dank für Eure Hinweise

PS: Folgende Links habe ich schon abgegrast:

http://www.hibernate.org/42.html
http://www.hibernate.org/105.html
http://www.hibernate.org/238.html
http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse
Last but not least, meine Anwendung: http://sourceforge.net/projects/ttraq/


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 31, 2005 9:08 am 
Beginner
Beginner

Joined: Sun May 29, 2005 4:03 pm
Posts: 24
Nicht wirklich, das Pattern ist generell für Webapps sehr gut, indem es die Transaktionen relativ kurz hält (man weiss ja nie wieviele User auf die DB einhämmern und wie lang die auf einer Web Page verbleiben)
Es dürfte aber (ich hab mich mit Hibernate3 und Struts noch nicht wirklich beschäftigt, ich verwende Hibernate2 und JSF)
eine Änderung geben, Hibernate3 verwendet meines Wissens nach unchecked exceptions und keine Checked Exceptions mehr, es kann sich also durchaus eine Vereinfachung des Error Handling Codes ergeben.

Generell kann ich Dir raten, schau Dir mal das Spring Framework als zusätzliche Zwischenschicht an, das abstrahiert und vereinfacht eben genau dieses Zugriffspattern ziemlich, indem Du automatisiert Aspekte einziehen kannst, die sich um die Session und Transaktionskapseln kümmern und Die Dir wenn Du auf Aspekte verzichtest, genau dieses Pattern sauber durchimplementieren und die Exceptions feiner granularisieren, sowie Fehler Interceptoren bereitstellen.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 31, 2005 9:12 am 
Beginner
Beginner

Joined: Sun May 29, 2005 4:03 pm
Posts: 24
Ach ja, hab ich vergessen, die Adresse für das Spring Framework ist:
www.springframework.org
ein sehr gutes Buch dazu ist Spring in Action von Mannings Publication wenn einem die Unterlagen der Webseite nicht reichen, die Ebook Version ist relativ billig und in der PDF Version druckbar.
www.manning.com


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 31, 2005 9:17 am 
Regular
Regular

Joined: Sun Aug 01, 2004 6:49 pm
Posts: 76
Ja, bin schon dabei mir das anzuschauen. Insbesondere Appfuse ist hier als Kickstarter für Applikationen interessant. Das integriert alle Bestandteile (Spring, Struts, Hibernate...)

Allerdings sträube ich mich noch ein bisschen zwecks Masse Spring noch mit reinzunehmen, ich werde mir aber auf jeden Fall mal die HibernateTemplate Umsetzung zu Gemüte führen.

Gruß
Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 31, 2005 9:24 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Wegen Hibernate Spring einzusetzen ist etwas daneben - mit Hibernate3 gibt es nur noch wenige triviale Gruende das zu tun. Wenn man andere Gruende hat mag das anders aussehen.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 31, 2005 9:32 am 
Beginner
Beginner

Joined: Sun May 29, 2005 4:03 pm
Posts: 24
Naja es gibt viele Gründe Spring einzusetzen und ja mit Hibernate3 ist einer der Gründe weggefallen nämlich das Mapping der Exceptions.
Aber Spring bietet doch einiges mehr:

Transaktionskapseln mittels AOP, generell AOP, eine größere Layer Unabhängigkeit durch generalisierte Exceptions, sauberes automatisiertes
handling der try catch Fehlerbehandlungsblöcke innerhalb von Transaktionskapseln,
sodass sich der Arbeitsaufwand beim DB Layer Wechsel reduziert (Auch beim Update innerhalb von Releases desselben Layers). Applikationsevents,
Eine komplette Middleware Unterstützungsinfrastruktur in Form eines sauberen service Systems, kapselung und Vereinfachung diverser Webservice Architekturen etc.... Inversion of object control.

Ich dachte ursprünglich auch dass Spring Overkill wäre nur als ich dann mal gegen ein Problem rannte wo ich einen kleinen Teil von Spring verwenden wollte hatte es mir schon Zeit gespart und mittlerweile nutze ich fast alle Layer von Spring, weil es einfach Sachen beinhaltet, die man in jeder Serverapplikation immer wieder braucht.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 31, 2005 9:36 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Reality check: man wechselt nicht die Persistenzschicht. Das ist reines Marketing. Klar, man hat oft ein paar JDBC calls irgendwo die man sauber einbinden will. Das kann man sich in 10 Zeilen selbst abstrahieren ohne sich ein ganzes Framework ins Haus zu holen. Und Transaktionsdemarkation deklarativ... das geht mit zig anderen Tools genauso. Mal davon abgesehen dass es einen gut funktionierenden Standard dafuer gibt, EJB session beans.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 31, 2005 10:52 am 
Beginner
Beginner

Joined: Sun May 29, 2005 4:03 pm
Posts: 24
Gegenreality check, oft gibt es Gründe sowas zu tun, die man selber nicht beeinflussen kann, in jedem mittelgroßen Projekt gibt es politische Gründe, die einem die Datenbank wegziehen können oder die einem zwingen die Persistenzschicht auszutauschen. Es gibt auch durchaus Gründe, ist bei Hibernate weniger der Fall, die einem technisch zwingen könnten das zu tun (Ging mir mal so in einem Projekt wo ich froh drüber gewesen wäre, die Persistenzschicht durch was anderes ersetzen zu können, ich hatte das Projekt damals geerbt).

Sprich mal als Beispiel, man setzt Hibernate ein und dann in irgendeinem Wahnsinnszustand meint das Management mal solle auf EJBs oder auf JDO umsteigen, aus Gründen was auch immer, es ist möglich wenn auch eine Heidenarbeit, wenn man gewisse Dinge aber bereits vorisoliert hat, wie das Transaktionshandling, wie die Sessions verwaltet werden, das Fehlerhandling,
dann Reduziert sich eben dieser Crossgrade Aufwand Doch um einiges.

Transaktionsdemarkation kann man mit EJB erreichen, ist sicher ein gangbarer Weg, nur oft will man keinen vollständigen EJB Server im Hintergrund laufen haben und EJB war vor EJB3.0 nicht wirklich genießbar, um es milde auszudrücken (ist meine persönliche Meinung) und hat sich genau aus diesem Grund auch bei den Entwicklern, die frei entscheiden konnten nicht sonderlich durchgesetzt.

Mit der 3er Release kann sich das aber ändern, hab mir neulich die Specs durchgelesen, die schaut ziemlich gut aus und ist auch stark von Hibernate beeinflusst.

Doch zurück zum Originalthema, ich hab genau deshalb Spring empfohlen, weil es in seinem Template... doInHibernate Pattern genau, dieses vom originalposter angesprochene Problem der Session und Transaktionsdauern sauber löst, indem es die Transaktionen möglichst abisoliert und die Sessions möglichst hält aber nicht gleichzeitig über Threads verteilt, so wie es sein soll, ohne dass man sich selber drum
kümmern muss. Wozu sich also selber drum kümmern?
Ich weiss Hibernate3 hat auch endlich die notwendigen Mechanismen drinnen, sodass man die bezüglich des Session sharings nicht mehr selber implementieren muss, aber Spring geht hier doch einiges weiter indem es die Transaktionsebene auch sauber abisoliert und zwar ohne, dass man seinen Code sonderlich stark mit Hibernate verdongeln muss.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 31, 2005 2:40 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Eine kleine Implementation dieser einfachen Abstraktion ist schon in der Hibernate Dokumentation mit HibernateUtil. Die komplexere gibts zum Downloand in CaveatEmptor, mit Anleitung in Hibernate in Action. Sind ca. 50 zeilen ziemlich langweiliger copy/paste code, bis jetzt brauche ich nichts anderes. In einem EJB container brauchts das natuerlich alles komplett nicht, Transaktion und Session sind automatisch gebunden.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 01, 2005 4:36 am 
Regular
Regular

Joined: Sun Aug 01, 2004 6:49 pm
Posts: 76
Schließlich habe ich das empfohlene "Pattern" von Hibernate gemäß dem Buch "Hibernate in Action" umgesetzt. Der Beispielcode ist in CaveatEmptor (HiA-SE) zu finden. Das wichtige ist die Filterung aller Requests über einen Servletfilter, damit die Session in den Views auch noch verfügbar ist, ansonsten müßte man alle Objekte und Collections vorher initialisieren.
Spring schien mir für diesen einen Zweck, wie angemerkt, zu aufwendig.

Man braucht keine Containerabhängigen Features wie JNDI oder ähnliches.

Folgende Komponenten sind also beteiligt:

HibernateSessionFilter kapselt alle Requests und beendet die aktuelle Sitzung:

Code:

... doFilter(...) {
    try {
        chain.doFilter(request, response);
        HibernateUtil.commitTransaction();
    } finally {
        HibernateUtil.closeSession();
    }
}


HibernateUtil managed via ThreadLocal die Session (siehe Beispielcode in CaveatEmptor)

Das Servlet oder die Action öffnen jediglich die Session, wenn diese gebraucht wird:

Code:
... execute(...) {
    try {
        HibernateUtil.beginTransaction();
        Session hibernateSession = HibernateUtil.getSession();
        <do some object/business code>
        <give it to your view>
    } catch (HibernateException) {
         ...
    }
}


Besten Dank an Werpu und Christian.

Christian: Danke für Eure (HibernateTeam) Geduld mit den immer wiederkehrenden Fragen, Hibernate ist echt toll und Euer Support wirklich tapfer.

Beste Grüße
Thomas

PS: Bleiben noch zwei Fragen offen:
1. Bitte erklärt doch mal kurz Transaktionsdemarkation
2. Ohne jetzt das allzu sehr in die Tiefe treten zu wollen, aber ich liess mir sagen ThreadLocal sei doch ziemlich ineffizient, spielt das Eurer Meinung nach mit neuerem Java keine Rolle mehr, oder sollte man hier bei hohen Anforderungen auch etwas ändern?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jun 01, 2005 6:10 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Der Code von CaveatEmptor ist fuer Hibernate 2.x, besser ins CVS schauen und den von "HiA-SE" nehmen. Aber auch der koennte noch etwas schlanker gemacht werden, was ich gerade tue. In einer zukuenftigen Hibernate-Version wird HibernateUtil auch ueberfluessig, da dann SessionFactory.getCurrentSession() ueberall funktioniert, nicht nur in einem EJB/JTA container.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.