Date: 2004-11-29T09:27:39
Editor: JohannesTextor <[EMAIL PROTECTED]>
Wiki: Cocoon Wiki
Page: CocoonAndHibernateTutorial
URL: http://wiki.apache.org/cocoon/CocoonAndHibernateTutorial
no comment
Change Log:
------------------------------------------------------------------------------
@@ -1,6 +1,6 @@
== Tutorial on using Hibernate with Cocoon ==
- TARGET-AUDIENCE: beginner '''*advanced*''' expert[[BR]]
-- COCOON-RELEASES: 2.1.5[[BR]]
+- COCOON-RELEASES: 2.1.5 2.1.6[[BR]]
- DOCUMENT-STATUS: '''*draft*''' reviewed released[[BR]]
----
@@ -280,7 +280,7 @@
or later experience the (in)famous Lazy Initialization Problem (tm). The
solution for this problem is to
create a servlet filter to manage Hibernate Sessions, so if you are'nt fed up
on Java yet read on :)
-== A Servlet Filter for Managing Hibernate Sessions ==
+== A Servlet Filter for Disposing Hibernate Sessions ==
=== Why ? ===
@@ -320,6 +320,22 @@
=== Creating the filter ===
+Our filter needs to communicate with cocoon. Unfortunately, this cannot be
done via the Avalon framework. I could not
+come up with a better solution than abusing the servlet session context for
this purpose.
+
+The example filter below will search the session context for an attribute
called {{{DisposeHibernateSession}}}. If found,
+it will try to cast the attribute value to a Hibernate Session, and close this
session and the related
+JDBC connection if successful.
+
+Note that the session is always flushed before closing. Like this, you can be
sure that any changes made to persistent
+objects are reflected in the database after the session has been closed. You
might want to alter this behaviour later
+on.
+
+To compile the filter you need the following jars in your classpath:
+
+* hibernate2.jar
+* servlet.jar (e.g. from the common/lib directory of a Tomcat distribution)
+
{{{
package org.test;
@@ -396,6 +412,45 @@
use the filter only on URLs that require the opening of a Hibernate session.
In that case,
modify the url-pattern accordingly. You may also define multiple filter
mappings.
+=== Using the filter ===
+
+Since the filter only cares for disposing open sessions, you still have to
open them yourself
+using the {{{PersistenceFactory}}} class designed above. Also you need to make
sure that every
+time a session is opened, it is correctly stored in the servlet session
context such that the
+filter will later close it.
+
+It might be a good idea to create a
+little helper function for doing this. I like to have the session as a global
variable since
+it is often used across functions during the processing of a pipeline. In the
code snippet below,
+this variable is called {{{hs}}}. From cocoon 2.1.6 onwards, an Exception will
be thrown if you
+do not explicitly declare this global variable. And oh, the package name ...
:)
+
+{{{
+var hs;
+
+function openHibernateSession()
+{
+ // Make sure Hibernate Sessions are not opened twice
+ if(hs && hs.isOpen())
+ return;
+
+ // Get new Session from PersistenceFactory
+ factory =
cocoon.getComponent(Packages.org.test.PersistenceFactory.ROLE);
+ hs = factory.createSession();
+ if (hs == null) {
+ throw new
Packages.org.apache.cocoon.ProcessingException("Hibernate session is null ");
+ }
+
+ // Release PersistenceFactory
+ cocoon.releaseComponent(factory);
+
+ // Send "Message" to HibernateFilter to dispose the session after the
view was rendered
+ cocoon.session.setAttribute("DisposeHibernateSession",hs);
+}
+}}}
+
+After calling {{{openHibernateSession()}}}, you are finally ready to use the
session for doing some
+Persistence.
== Appendix ==