Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Cocoon Wiki" for change 
notification.

The following page has been changed by PeteFarmer:
http://wiki.apache.org/cocoon/CocoonAndHibernateTutorial

The comment on the change is:
fixed a few tiny but significant typos, added note for Hibernate3 DOCTYPE

------------------------------------------------------------------------------
  
  2005/08/10:
  
- Finally added a minimal example to show how Cocoon and Hibernate interact. 
+ Finally added a minimal example to show how Cocoon and Hibernate interact.
  
- 2005/07/25: 
+ 2005/07/25:
  
  If you have visited this page before, you should check out the new Servlet 
Filter. It now
  finally uses the request object instead of the servlet session to communicate 
with cocoon,
- with is MUCH cleaner and most importantly does not require the creation of a 
Session ... 
+ with is MUCH cleaner and most importantly does not require the creation of a 
Session ...
- Sorry for taking so long to clean this up ! 
+ Sorry for taking so long to clean this up !
  
- I am now using all of the code in a project with Hibernate 3. Probably the 
code snippets will 
+ I am now using all of the code in a project with Hibernate 3. Probably the 
code snippets will
- soon be updated to use the new Hibernate version by default. 
+ soon be updated to use the new Hibernate version by default.
  
  === What you will get from this page ===
  
- This page proposes a very basic way of using Hibernate from your Cocoon 
application. This is '''not''' an 
+ This page proposes a very basic way of using Hibernate from your Cocoon 
application. This is '''not''' an
  introduction to Hibernate or Cocoon itself. It just covers the specific 
issues of integration
- between the two. 
+ between the two.
  
- The approach presented here is very simple in that it tries to use facilities 
already provided by 
+ The approach presented here is very simple in that it tries to use facilities 
already provided by
  Cocoon to perform database connection pooling. However, without using another 
framework you will have
  direct interaction between Hibernate and Cocoon, which means calling 
Hibernate from flowscript. Many
  people don't want to do this and prefer to use the Spring framework for 
additional abstraction. If
- you are not sure if this approach is right for you, make sure you read the 
"Conceptual Overview" 
+ you are not sure if this approach is right for you, make sure you read the 
"Conceptual Overview"
- section first. 
+ section first.
  
  === Topics covered ===
  
- The two main problems you have when integrating Hibernate into Cocoon are the 
following: 
+ The two main problems you have when integrating Hibernate into Cocoon are the 
following:
  
- * Hibernate's builtin connection pool is for testing purposes only, so sooner 
or later you will have to use another one. 
+ * Hibernate's builtin connection pool is for testing purposes only, so sooner 
or later you will have to use another one.
  
- * When persistent objects are navigated by the view, closing Hibernate 
sessions from flowscript (=the control) 
+ * When persistent objects are navigated by the view, closing Hibernate 
sessions from flowscript (=the control)
-  may lead to exceptions due to race conditions. 
+  may lead to exceptions due to race conditions.
  
- The approach presented here addresses these problems by covering the 
following topics: 
+ The approach presented here addresses these problems by covering the 
following topics:
  
- * Installing Hibernate 
+ * Installing Hibernate
  
  * Configuring Hibernate to use cocoon.xconf datasources
  
- * Setting up a Servlet Filter for managing the disposal of Hibernate sessions 
+ * Setting up a Servlet Filter for managing the disposal of Hibernate sessions
  
  === Your basic skills ===
  
- Time. If you are new to the topic of O/R mapping, you will need a lot 
+ Time. If you are new to the topic of O/R mapping, you will need a lot
  of time and patience, because it is not an easy topic. Learning Cocoon already
  made you re-think your concept of a Web Application; learning Hibernate, you
- will have to do it again. 
+ will have to do it again.
  
  You should have basic Cocoon knowledge, i.e. about the Sitemap, Flowscript,
- and JX Templates. The samples included will also use CForms. Did I mention 
+ and JX Templates. The samples included will also use CForms. Did I mention
- Flowscript ? That one is especially important. 
+ Flowscript ? That one is especially important.
  
  If you want to use Hibernate you should also be fluent in Java. Be warned that
- you are going beyond the "no programming required" - statement of the Cocoon 
+ you are going beyond the "no programming required" - statement of the Cocoon
- definition. If you want to understand what you are doing, you should have a 
+ definition. If you want to understand what you are doing, you should have a
  basic notion of what Avalon is. We are also going to write a Servlet Filter 
which
- takes care of Hibernate Session, so if you don't know what a Servlet Filter 
is 
+ takes care of Hibernate Session, so if you don't know what a Servlet Filter is
- get your favourite book or search engine and read up :) 
+ get your favourite book or search engine and read up :)
  
  You will have a basic notion of what Hibernate is and what it does, otherwise
  you would not have come to this page :) But make sure you have understood what
- lazy collection initialization is and what it does. 
+ lazy collection initialization is and what it does.
  
  === Technical prerequisites ===
  
- A running cocoon installation. I tried this on Cocoon 2.1.6 and Cocoon 2.1.7. 
+ A running cocoon installation. I tried this on Cocoon 2.1.6 and Cocoon 2.1.7.
  This is written for Hibernate v 2.1.X, but it also works with Hibernate 3.0.
  When using Hibernate 3, you'll have to adjust the Hibernate package name,
  which has changed from {{{net.sf.hibernate}}} to {{{org.hibernate}}}.
@@ -84, +84 @@

  
  === Conceptual overview ===
  
- The approach presented here is built to work with Cocoon and Hibernate alone, 
+ The approach presented here is built to work with Cocoon and Hibernate alone,
  without any further frameworks. This creates a dependency between Cocoon and 
Hibernate since
  you will need to manage Hibernate sessions from flow script. Creating such a 
dependency
  is considered bad design by many people. For example, you might build a 
webshop which
  stores articles in a database. Using Hibernate, you will be able to replace 
the database
- without too much hassle (switching from MySQL to Oracle, for example), but it 
will still 
+ without too much hassle (switching from MySQL to Oracle, for example), but it 
will still
  be a database. When you want to manage your articles via a remote web service 
(or a flat
  text file or whatever means of data storage), you'll have to rewrite your 
flowscript.
  
- You can avoid this dependency by using an additional framework like Spring or 
Avalon which 
+ You can avoid this dependency by using an additional framework like Spring or 
Avalon which
  supports the "Inversion of Control" and "Data Access Object" design patterns. 
This will yield
- a cleaner and more modular designed web application. 
+ a cleaner and more modular designed web application.
  
  So before you begin, think if the approach presented here is right for you. I 
use it for smaller
- projects, when even a change in the underlying database is very unlikely, and 
I know the 
+ projects, when even a change in the underlying database is very unlikely, and 
I know the
  customer will never switch to something else than a database for data 
storage. Moreover, adding
- yet another framework - like Spring - to the mix, the learning curve for new 
developers gets 
+ yet another framework - like Spring - to the mix, the learning curve for new 
developers gets
- even steeper, and the resulting web application even larger, which is too 
costly for some 
+ even steeper, and the resulting web application even larger, which is too 
costly for some
- projects. 
+ projects.
  
- However, if you have a larger application or want a clean implementation of 
the IOC and DAO 
+ However, if you have a larger application or want a clean implementation of 
the IOC and DAO
- design patterns, you should definately have a look at the Spring framework. 
The starting 
+ design patterns, you should definately have a look at the Spring framework. 
The starting
- point is the SpringPetstore at cocoondev.org. 
+ point is the SpringPetstore at cocoondev.org.
  
  == Setting up ==
  
- First of all, you need an active database connection set up and configured in 
cocoon.xconf. 
+ First of all, you need an active database connection set up and configured in 
cocoon.xconf.
  There are several wiki and documentation pages on how to do this. For 
instance, if you use
- MySQL have a look at [MySQL]. 
+ MySQL have a look at [MySQL].
  
- For now, I will assume that your SQL datasource is named "test". 
+ For now, I will assume that your SQL datasource is named "test".
  
  Now download hibernate from [http://www.hibernate.org]. I tried this with the 
current production
- release, 2.1.6. The following jars from the Hibernate distribution need to be 
copied to your 
+ release, 2.1.6. The following jars from the Hibernate distribution need to be 
copied to your
  WEB-INF/lib directory:
  
  * hibernate2.jar
  
- From the "lib" directory of the Hibernate distribution: 
+ From the "lib" directory of the Hibernate distribution:
  
- * dom4j-1.4.jar 
+ * dom4j-1.4.jar
  * cglib-full-2.0.2.jar
  * jta.jar
  
  If you build cocoon exclude ojb block,this lib requried too:
  * odmg-3.0.jar
  
- '''Hibernate 3 note''': Hibernate 3 also depends on "asm.jar" and 
"asm-attrs.jar". 
+ '''Hibernate 3 note''': Hibernate 3 also depends on "asm.jar" and 
"asm-attrs.jar".
  In Cocoon 2.1.7, these JARs are already provided in the WEB-INF/lib directory.
- Unfortunately, the versions provided by Cocoon are not compatible with 
+ Unfortunately, the versions provided by Cocoon are not compatible with
  Hibernate 3. You'll have to delete those JARs and replace them with those 
shipped
- with Hibernate, although i'm not sure if some parts of Cocoon rely on those 
+ with Hibernate, although i'm not sure if some parts of Cocoon rely on those
- particular versions (it works fine for me so far). 
+ particular versions (it works fine for me so far).
  
  == Registering Hibernate with Avalon ==
  
- Now we will register Hibernate with Cocoon. If you are like me, you will 
+ Now we will register Hibernate with Cocoon. If you are like me, you will
- fire up Eclipse to accomplish the following part. 
+ fire up Eclipse to accomplish the following part.
  
- The first thing we'll do is create an interface {{{PersistenceFactory}}} that 
+ The first thing we'll do is create an interface {{{PersistenceFactory}}} that
- extends the Component interface from Avalon: (Note: {{{PersistenceFactory}}} 
+ extends the Component interface from Avalon: (Note: {{{PersistenceFactory}}}
  and {{{HibernateFactory}}} originate from the Page CformsHibernateAndFlow!)
  
  {{{
- package org.test; // Put the name of the target package here. Using the 
default package is not recommended! 
+ package org.test; // Put the name of the target package here. Using the 
default package is not recommended!
-       
+ 
  import org.apache.avalon.framework.component.Component;
-       
+ 
  public interface PersistenceFactory extends Component {
        String ROLE = PersistenceFactory.class.getName();
-       
+ 
        public net.sf.hibernate.Session createSession();
  }
- }}} 
+ }}}
  
- As you can see the {{{PersistenceFactory}}} will be responsible for the 
creation 
+ As you can see the {{{PersistenceFactory}}} will be responsible for the 
creation
- of Hibernate Sessions. This is the point where we'll have to decide how 
Hibernate will 
+ of Hibernate Sessions. This is the point where we'll have to decide how 
Hibernate will
  connect to the database. My preffered solution is using the cocoon connection 
pool.
  
- However, most tutorials will tell you to create a file called 
hibernate.properties and 
+ However, most tutorials will tell you to create a file called 
hibernate.properties and
  put your database access information in there. This will work, but Hibernate 
will use its
- own builtin connection pool, and the documentation states clearly that 
''''the Hibernate 
+ own builtin connection pool, and the documentation states clearly that 
''''the Hibernate
- builtin connection pool is not for production use''''. 
+ builtin connection pool is not for production use''''.
  
  For example, when using MySQL, you will experience problems when leaving the 
webapp running
- overnight and coming back in the morning. MySQL connections die after 8 hours 
of idletime, and the 
+ overnight and coming back in the morning. MySQL connections die after 8 hours 
of idletime, and the
  Hibernate builtin pool is not capable of dealing with this. So the first 
thing you will see
  is an error message. It goes away after reloading the page, but still it's 
unacceptable for
  production use. That's why I encourage you to spend the little extra effort 
and use Coccoon
- connection pooling right away. 
+ connection pooling right away.
  
- Where we will do this is in the actual implementation of the 
{{{PersistenceFactory}}} interface, 
+ Where we will do this is in the actual implementation of the 
{{{PersistenceFactory}}} interface,
- in a class called {{{HibernateFactory}}} 
+ in a class called {{{HibernateFactory}}}
  
  '''IMPORTANT NOTE:''' Make sure you check out the comments in 
{{{initialize()}}} for instructions on how to add persistent
- classes. If you are using this to port an existing Hibernate / Cocoon 
application to the Cocoon 
+ classes. If you are using this to port an existing Hibernate / Cocoon 
application to the Cocoon
- connection pool, you will need to change that part according to your 
configuration. 
+ connection pool, you will need to change that part according to your 
configuration.
  
  {{{
  package org.test;
@@ -198, +198 @@

  import org.apache.avalon.excalibur.datasource.DataSourceComponent;
  import org.apache.avalon.framework.service.ServiceSelector;
  
- // import all classes from your package so you can later persist them  
+ // import all classes from your package so you can later persist them
  import org.test.*;
  
  public class HibernateFactory
@@ -258, +258 @@

                cfg = new net.sf.hibernate.cfg.Configuration();
  
                /* ***** ADD PERSISTENT CLASSES, VARIANT 1 ***** */
-               // persistent classes can be added here using 
+               // persistent classes can be added here using
  
-               // cfg.addClass(org.test.myClass.class); 
+               // cfg.addClass(org.test.myClass.class);
  
-               // Make sure the corresponding .class and .hbm.xml files are 
located in 
+               // Make sure the corresponding .class and .hbm.xml files are 
located in
-               // (the same directory of) your classpath (e.g. 
WEB-INF/classes) 
+               // (the same directory of) your classpath (e.g. WEB-INF/classes)
                sf = cfg.buildSessionFactory();
  
                /* ***** ADD PERSISTENT CLASSES, VARIANT 2 ***** */
              // alternatively, you might be using a hibernate.cfg.xml file to 
load mappings,
-               // then use the following line instead: 
+               // then use the following line instead:
  
                // sf = cfg.configure().buildSessionFactory();
  
                // no additional cfg.addClass(...) statements needed, since you 
can define
-               // mappings in the XML config file 
+               // mappings in the XML config file
          }
          catch ( Exception e) {
                getLogger().error("Hibernate:" + e.getMessage());
@@ -305, +305 @@

      public net.sf.hibernate.Session createSession() {
        net.sf.hibernate.Session hs;
        DataSourceComponent datasource = null;
-       
+ 
-       // When creating a session, use a connection from 
+       // When creating a session, use a connection from
-         // cocoon's connection pool 
+         // cocoon's connection pool
-       try {                   
+       try {
-       // Select the DataSourceComponent named "test" 
+       // Select the DataSourceComponent named "test"
-         // This is a normal SQL connection configured in cocoon.xconf 
+         // This is a normal SQL connection configured in cocoon.xconf
                ServiceSelector dbselector =
              (ServiceSelector) 
manager.lookup(DataSourceComponent.ROLE+"Selector");
-         datasource = (DataSourceComponent) dbselector.select("test"); 
+         datasource = (DataSourceComponent) dbselector.select("test");
                //name as defined in cocoon.xconf
                hs = sf.openSession(datasource.getConnection());
        }
@@ -326, +326 @@

  }
  }}}
  
- The crucial part is createSession(), where we tell Hibernate to use a 
connection from the 
+ The crucial part is createSession(), where we tell Hibernate to use a 
connection from the
- Cocoon pool. This connection is selected using the avalon framework API. 
+ Cocoon pool. This connection is selected using the avalon framework API.
  
- Compile these two files. I needed the following jars in my classpath: 
avalon-framework-api-4.1.5.jar, 
+ Compile these two files. I needed the following jars in my classpath: 
avalon-framework-api-4.1.5.jar,
- excalibur-datasource-1.1.1.jar, and hibernate2.jar. All these should be in 
your WEB-INF/lib 
+ excalibur-datasource-1.1.1.jar, and hibernate2.jar. All these should be in 
your WEB-INF/lib
- folder anyway. When you're done, copy the .class files to a directory 
"org/test" (which obviously 
+ folder anyway. When you're done, copy the .class files to a directory 
"org/test" (which obviously
  depends on the package name you chose) in the "WEB-INF/classes/" folder of 
your cocoon installation.
  
- To register your {{{HibernateFactory}}} with Cocoon, put the following line 
in cocoon.xconf: 
+ To register your {{{HibernateFactory}}} with Cocoon, put the following line 
in cocoon.xconf:
  
  {{{
        <component class="org.test.HibernateFactory" 
role="org.test.PersistenceFactory"/>
  }}}
  
  (Not sure whether it is actually important where you put this. There is a 
bunch of other component ... class ...
- statements in cocoon.xconf, so I just put mine above the Xalan XSLT processor 
component. Need some feedback here!) 
+ statements in cocoon.xconf, so I just put mine above the Xalan XSLT processor 
component. Need some feedback here!)
  
- Now, you need a hibernate.properties file in your "WEB-INF/classes" folder. A 
very basic config file I 
+ Now, you need a hibernate.properties file in your "WEB-INF/classes" folder. A 
very basic config file I
- use is the following: 
+ use is the following:
  
  {{{
  hibernate.cglib.use_reflection_optimizer = false
@@ -353, +353 @@

  }}}
  
  It basically tells hibernate to turn off the reflection optimizer (whatever 
that means? :) ) and the
- statement cache (although statement caching can boost performance, you should 
leave it turned off until you 
+ statement cache (although statement caching can boost performance, you should 
leave it turned off until you
- are really sure how to use it). The most important line is where you tell 
Hibernate about the actual SQL 
+ are really sure how to use it). The most important line is where you tell 
Hibernate about the actual SQL
  dialect you are using. If you do not supply this information, Hibernate won't 
be able to behave accordingly.
  For example, Hibernate will try to use subqueries which are not supported if 
you use MySQL.
  
  Now restart cocoon. If everything went right, you will see the following line 
in your servlet container log
- file (catalina.out if you are using Tomcat): 
+ file (catalina.out if you are using Tomcat):
  
  {{{ Hibernate initialize called }}}
  
  This means that Hibernate is ready for action. At this point you may start to 
deploy your beans and store,
- get and edit them following the instructions on the Yet To Be Written page. 
+ get and edit them following the instructions on the Yet To Be Written page.
  
- However, at some point you will notice that there is still no proper way of 
managing Hibernate Sessions. 
+ However, at some point you will notice that there is still no proper way of 
managing Hibernate Sessions.
  Of course you can create and dispose Hibernate Session from Flow Script, but 
very probably you will sooner
  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 :) 
+ create a servlet filter to manage Hibernate Sessions, so if you are'nt fed up 
on Java yet read on :)
  
  == A Servlet Filter for Disposing Hibernate Sessions ==
  
  === Why ? ===
  
  (If you just want to continue installing and are not bothering about the Why, 
skip this part and come
- back later ...) 
+ back later ...)
  
  If you're getting serious about Hibernate, sooner or later you will want to 
use lazy collection initialization
  (Read the corresponding section in GettingStartedWithCocoonAndHibernate for 
an introduction on this topic).
- Say you are accessing Hibernate sessions from flowscript, i.e. as follows: 
+ Say you are accessing Hibernate sessions from flowscript, i.e. as follows:
  
  {{{
    var factory = 
cocoon.getComponent(Packages.org.test.PersistenceFactory.ROLE);
@@ -388, +388 @@

  
    var data = hs.find("from org.test.Data");
  
-   cocoon.sendPage("data-pipe", {data: data} ); 
+   cocoon.sendPage("data-pipe", {data: data} );
  
    hs.close();
  }}}
@@ -399, +399 @@

  won't load its items from the database. But it is still possible that your 
view pipeline wants to access {{{otherData}}}.
  
  Now the problem is that the flowscript will just continue to process right 
after it has invoked the view pipeline,
- so it is possible that the {{{hs.close()}}} will occur BEFORE your view has 
rendered completely. So when the view 
+ so it is possible that the {{{hs.close()}}} will occur BEFORE your view has 
rendered completely. So when the view
- will access {{{otherData}}} after that, you will get an exception telling you 
that Hibernate failed to lazily 
+ will access {{{otherData}}} after that, you will get an exception telling you 
that Hibernate failed to lazily
- initialize the collection. A classical Race Condition. 
+ initialize the collection. A classical Race Condition.
  
- Obviously that's no good. The solution is to move Hibernate session disposal 
out of the flowscript layer and even 
+ Obviously that's no good. The solution is to move Hibernate session disposal 
out of the flowscript layer and even
- out of cocoon. I.e., we will create a servlet filter. A servlet filer is 
invoked before the request is passed to cocoon 
+ out of cocoon. I.e., we will create a servlet filter. A servlet filer is 
invoked before the request is passed to cocoon
  and will be notified when the request is processed completely. At that point 
we can safely close the Hibernate session,
  given we will not continue to work with it from flowscript after the view 
pipeline has been invoked. However, invoking
  the view pipeline should be the last thing you do in a flow script anyway, so 
that won't be too much of a problem.
  
  === Creating the filter ===
  
- Our filter needs to communicate with cocoon. Unfortunately, this cannot be 
done via the Avalon framework. The most 
+ Our filter needs to communicate with cocoon. Unfortunately, this cannot be 
done via the Avalon framework. The most
- straightforward way to get around this limitation is using the request 
object. 
+ straightforward way to get around this limitation is using the request object.
  
  The example filter below will search the current request 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 
+ it will try to cast the attribute value to a Hibernate Session, and close 
this session and the related
- JDBC connection if successful. 
+ 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. 
+ 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) 
+  * servlet.jar (e.g. from the common/lib directory of a Tomcat distribution)
  
  {{{
  package org.test;
@@ -453, +453 @@

  
    public void doFilter(ServletRequest request, ServletResponse response,
                       FilterChain chain) throws IOException, ServletException {
-     // Pass the request on to cocoon 
+     // Pass the request on to cocoon
      chain.doFilter(request, response);
-     
+ 
-     // After cocoon has finished processing, close the 
+     // After cocoon has finished processing, close the
-     // corresponding Hibernate session if it has been opened 
+     // corresponding Hibernate session if it has been opened
      if( request.getAttribute("DisposeHibernateSession") != null )
      {
       Session hs = (Session) request.getAttribute("DisposeHibernateSession");
@@ -481, +481 @@

  === Installing the filter ===
  
  In the file WEB-INF/web.xml, insert the following code avove the "Servlet 
Configuration" part: (as always, insert
- your favourite package name) 
+ your favourite package name)
  
  {{{
  <!-- Filter Configuration ========================================== -->
@@ -497, +497 @@

  </filter-mapping>
  }}}
  
- This tells the container to invoke our filter on all requests. That is OK 
since our filter 
+ This tells the container to invoke our filter on all requests. That is OK 
since our filter
- will only dispose sessions that have previously been opened. However, you 
might want to 
+ will only dispose sessions that have previously been opened. However, you 
might want to
  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.
  
@@ -507, +507 @@

  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 request such 
that the
- filter will later close it. 
+ 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 ... 
:) 
+ do not explicitly declare this global variable. And oh, the package name ... 
:)
  
  {{{
- var hs; 
+ 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);
+       var factory = 
cocoon.getComponent(Packages.org.test.PersistenceFactory.ROLE);
        hs = factory.createSession();
-       if (hs == null) { 
+       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.request.setAttribute("DisposeHibernateSession",hs);
  }
  }}}
  
- After calling {{{openHibernateSession()}}}, you are finally ready to use the 
session for doing some 
+ After calling {{{openHibernateSession()}}}, you are finally ready to use the 
session for doing some
- Persistence. 
+ Persistence.
  
- Note: 
+ Note:
  Of course now you need to make sure that you manage a session (I.E. add the 
session action to your pipeline). If you will not add the session management, 
the filter will crash with "Cannot create a session after the response has been 
committed".
  
  === A first Example ===
  
- "Now that Hibernate is installed, how do I continue?" - Well the answer is up 
to you, since there are so many ways of using Hibernate. What follows is some 
kind of a minimal example so you get a feeling how Hibernate '''could''' 
interact with Cocoon. 
+ "Now that Hibernate is installed, how do I continue?" - Well the answer is up 
to you, since there are so many ways of using Hibernate. What follows is some 
kind of a minimal example so you get a feeling how Hibernate '''could''' 
interact with Cocoon.
  
- In this example we'll use Hibernate to manage a list of ISO language codes. 
So the first thing we need is a Java Bean that represents those language codes. 
Our bean will just have two attributes, the code and a name for each language, 
plus a numerical ID (I use one for each and every class). The code doesn't look 
all that interesting: 
+ In this example we'll use Hibernate to manage a list of ISO language codes. 
So the first thing we need is a Java Bean that represents those language codes. 
Our bean will just have two attributes, the code and a name for each language, 
plus a numerical ID (I use one for each and every class). The code doesn't look 
all that interesting:
  
  {{{
  package org.test;
@@ -559, +559 @@

        private String IsoCode;
        private String Name;
        /**
-        * 
+        *
         */
        public DCLanguage() {
                super();
@@ -604, +604 @@

  }
  }}}
  
- Compile this class and store it in the corresponding subfolder of 
WEB-INF/classes (Package name ...). 
+ Compile this class and store it in the corresponding subfolder of 
WEB-INF/classes (Package name ...).
- Next, we shall create a table in our database to store the objects in. 
+ Next, we shall create a table in our database to store the objects in.
  
  {{{
  CREATE TABLE `dclanguage` (
@@ -616, +616 @@

  )
  }}}
  
- Fill in some sample values, or use the following if you're too lazy: :) 
+ Fill in some sample values, or use the following if you're too lazy: :)
  
  {{{
   INSERT INTO `dclanguage` VALUES (1,'de','german');
@@ -627, +627 @@

   INSERT INTO `dclanguage` VALUES (6,'da','danish');
  }}}
  
- The glue between our POJO and the SQL table is the hibernate mapping 
definition. This is an XML file which should be called 
{{{DCLanguage.hbm.xml}}}, since our class is called {{{DCLanguage.class}}}. 
Create the file with the following content and put it into the subfolder of 
WEB-INF/classes where your DCLanguage class resides: 
+ The glue between our POJO and the SQL table is the hibernate mapping 
definition. This is an XML file which should be called 
{{{DCLanguage.hbm.xml}}}, since our class is called {{{DCLanguage.class}}}. 
Create the file with the following content and put it into the subfolder of 
WEB-INF/classes where your DCLanguage class resides:
  
  {{{
  <?xml version="1.0"?>
@@ -645, +645 @@

  </hibernate-mapping>
  }}}
  
- Attention, there is a catch: The {{{<generator class="native"/>}}} only works 
if your database is able to generate IDs automatically. (MySQl, for example, 
is). Refer to the Hibernate documentation if that does not hold in your case 
(HSQL?). 
+ Attention, there is a catch: The {{{<generator class="native"/>}}} only works 
if your database is able to generate IDs automatically. (MySQl, for example, 
is). Refer to the Hibernate documentation if that does not hold in your case 
(HSQL?).
  
- Note that Hibernate comes with some tools which can automatically generate 
Java and SQL source code from a mapping file. They only work up to a certain 
level of complexity, though. 
+ Note that Hibernate comes with some tools which can automatically generate 
Java and SQL source code from a mapping file. They only work up to a certain 
level of complexity, though.
  
+ One other thing to note: make sure that the DOCTYPE declaration is correct 
for the version of Hibernate which you are using. Hibernate3 will need this:
+ {{{
+ <!DOCTYPE hibernate-mapping PUBLIC
+       "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+       "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd";>
+ }}}
+ 
- Now you're almost done. Just insert the following statement: 
+ Now you're almost done. Just insert the following statement:
  
  {{{cfg.addClass(DCLanguage.class);}}}
  
- into the {{{HibernateFactory}}} (see ''ADD PERSISTENT CLASSES, VARIANT 1'' in 
the source code), recompile it, overwrite it in WEB-INF/classes and restart 
Cocoon. Congratulations, you should now be able to manage your ISO language 
codes via Hibernate and Cocoon :) 
+ into the {{{HibernateFactory}}} (see ''ADD PERSISTENT CLASSES, VARIANT 1'' in 
the source code), recompile it, overwrite it in WEB-INF/classes and restart 
Cocoon. Congratulations, you should now be able to manage your ISO language 
codes via Hibernate and Cocoon :)
  
- To verify this, create a testing sub-sitemap, attach a flowscript and insert 
the following function into it: 
+ To verify this, create a testing sub-sitemap, attach a flowscript and insert 
the following function into it:
  
  {{{
  function language_list()
  {
-       openHibernateSession(); // as defined in Tutorial 
+       openHibernateSession(); // as defined in Tutorial
  
        var languages = hs.find("from org.test.DCLanguage order by IsoCode 
asc");
                // HQL String to get a list of all beans, ordered by their 
IsoCode
-       
+ 
-       cocoon.sendPage("language-list.jxt", { 
+       cocoon.sendPage("language-list.jxt", {
                languages:languages
-       }); // Send objects to the view layer (here: JX Template) 
+       }); // Send objects to the view layer (here: JX Template)
  
-       // Hibernate Session will be closed automatically 
+       // Hibernate Session will be closed automatically
-       // by the servlet filter 
+       // by the servlet filter
  }
  }}}
  
- Create the corresponding pipelines in your sitemap: 
+ Create the corresponding pipelines in your sitemap:
  
  {{{
  <map:match pattern="language-list.jxt">
-       <map:generate type="jxt" src="documents/language-list.jxt"/>
+       <map:generate type="jx" src="documents/language-list.jxt"/>
        <map:serialize type="xml"/>
  </map:match>
  
@@ -687, +694 @@

  </map:match>
  }}}
  
- And save the following as {{{documents/language-list.jxt}}} (relative to your 
sitemap): 
+ And save the following as {{{documents/language-list.jxt}}} (relative to your 
sitemap):
  
  {{{
  <?xml version="1.0" encoding="iso-8859-1"?>
@@ -698, +705 @@

  </languages>
  }}}
  
- Alas, you're done. Surf to "base-uri-of-your-sitemap"/language-list and 
contemplate the power of Cocoon and Hibernate :) 
+ Alas, you're done. Surf to "base-uri-of-your-sitemap"/language-list and 
contemplate the power of Cocoon and Hibernate :)
  
- As said before, this is a minimal example. Now you're ready to continue on 
your own, the Hibernate docs will be your friend. Note that this example does 
not represent the recommended way of doing things - particularly since your 
querying your objects from Flowscript. Many people will rather want to do this 
from a Data Access Object (DAO) written in Java. The next part of this tutorial 
will cover this. 
+ As said before, this is a minimal example. Now you're ready to continue on 
your own, the Hibernate docs will be your friend. Note that this example does 
not represent the recommended way of doing things - particularly since your 
querying your objects from Flowscript. Many people will rather want to do this 
from a Data Access Object (DAO) written in Java. The next part of this tutorial 
will cover this.
  
  == Appendix ==
  

Reply via email to