<?xml version="1.0"?>
<!-- 
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 -->

<document>

  <properties>
    <title>Hibernate Howto</title>
  </properties>

  <body>

    <section name="Introduction">
      <p>
        This is a HOWTO on implementing Hibernate as the database OM layer.  The motivating factors for using Hibernate
        are:
        <ol>
          <li>
      You just use POJO (Plain Old Java Objects) versus generated objects.
          </li>
          <li>
      You can either start with Java objects and create your database schema from there, or 
      start with a database schema, and map the Java objects to the schema.
          </li>
          <li>
      Extensive performance optimizations built into the Hibernate engine.
          </li>          
          <li>
      Leverage Avalon component use in Turbine 2.3!
          </li>                    
        </ol>
      </p>
      <p>
        Please review the content available from the Hibernate homepage.  This howto assumes
        you already are confortable with the various Hibernate concepts.
      </p>
      <p>
    In this example, we will take a simple schema with a single table and integrate Hibernate into
    a Turbine action.  We will talk about best practices for Hibernate and Turbine.
        <ol>
          <li>
        Configure project dependencies.
          </li>        
          <li>
        Directory Structures
          </li>
    
          <li>
        Setup Avalon component configuration.
          </li>
          
          <li>
          Setup Hibernate mapping files.
          </li>
          <li>
          Create static ServiceLocator class.
          </li>          
          <li>
            Create filter that manages the Hibernate Session.
          </li>
          <li>
            Setup PersitenceException handling
          </li>          
        </ol>
      </p>

    </section>

    <section name="Directory Structures">
      <p>
      While you can organize your directory structure however you like, I tend to have structure like:
      </p>
      <source>
      /src/java/com/my/project/bizobj business objects reside
      /src/java/com/my/project/om POJO objects mapped to database reside
      /src/java/com/my/project/om/persist manager objects that faciliate retrieve POJO objects
      /src/java/com/my/project/om/filter Servlet Filter lives that maintains the Hibernate Session 
      /src/java/ where hibernate.hbm.xml and hibernate.cfg.xml files live
      
    </source>

    </section>

    <section name="Configure project dependencies" >
      <p>
        The easiest way to maintain a project is to use Maven.  Here are the sample
        dependencies for your project.xml.
      </p>
      <source>
<![CDATA[
    <dependency>
      <id>hibernate</id>      
      <version>2.0-beta6</version>
      <properties>        
      <war.bundle.jar>true</war.bundle.jar>
      </properties>
    </dependency>  
    <dependency>
      <id>hibernate:hibernate-avalon</id>
      <version>0.1</version>
      <properties>        
      <war.bundle.jar>true</war.bundle.jar>
      </properties>              
    </dependency>  
    <dependency>
      <id>dom4j</id>      
      <version>1.4</version>
      <properties>        
      <war.bundle.jar>true</war.bundle.jar>
      </properties>
    </dependency>       
    <dependency>
      <id>cglib</id>      
      <version>rc2-1.0</version>
      <properties>        
      <war.bundle.jar>true</war.bundle.jar>
      </properties>
    </dependency>                          
    <dependency>
      <id>jcs</id>      
      <version>1.0-dev</version>
      <properties>        
      <war.bundle.jar>true</war.bundle.jar>
      </properties>
    </dependency>                       
]]>
      </source>     
      <p>
        The key jar file is the hibernate-avalon.jar file, it contains the Avalon wrapper
        for Hibernate, and can be used with any Avalon container.
      </p>
        
    </section>

    <section name="Setting up Avalon Configuration" >

        <p>
      We leverage the Avalon based HibernateService that is hosted as part of the
      HibernateExt project.  You must specify the name of the service, as well as the implementing
      service in your componentConfiguration.xml file.  Other configuration parameters can be passed
      in as well.
        </p>
      <source>
<![CDATA[

<my-system>
  <component
    role="net.sf.hibernate.avalon.HibernateService"
    class="net.sf.hibernate.avalon.HibernateServiceImpl">
  </component>
</my-system>
                      
]]>
      </source>     

        <p>
      The componentRoles file also defines how to access the component.  Here is a 
      very simple componentRoles.xml file:
        </p>
      <source>
<![CDATA[

<role-list>
 <role
    name="net.sf.hibernate.avalon.HibernateService"
    shorthand="hibernate"
    default-class="net.sf.hibernate.avalon.HibernateServiceImpl"/>   
</role-list>
                      
]]>
      </source>             
    </section>
      
      

    <section name="Setup Hibernate mapping files">
      <p>
    This section will not go into depth on how to configure the hibernate.cfg.xml and
    hibernate.hbm.xml files.  However, if you don't specify in the componentConfiguration.xml
    file where they are located, then they should be placed in your src/java/ directory.
      </p>
      <p>
        The exact configuration is dependent on the environment Turbine is running in, however
        I highly recommend that you use the JNDI look up of the datasource, and use DBCP for your
        connection pooling.  I have found that when using Hibernate in cactus tests, you may need to
        increase the pool size required in order to not run out of connections, however this doesn't
        seem to apply to running as a web application.
      </p>
    </section>



    <section name="Create static ServiceLocator class.">
      <p>
    Currently this class is not integrated into Turbine, so you will need to provide an implemation yourself.
    This provides a static method of retrieving your Hibernate Session.
      </p>
     
        <source>
<![CDATA[
package com.upstate.cellculture.om.persist;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.JDBCException;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * This class is used to get Hibernate Sessions and may
 * also contain methods (in the future) to get DBConnections
 * or Transactions from JNDI.
 */
public class ServiceLocator
{
    //~ Static fields/initializers =============================================
    public final static String SESSION_FACTORY = "hibernate/sessionFactory";
    public static final ThreadLocal session = new ThreadLocal();
    private static SessionFactory sf = null;
    private static ServiceLocator me;
    private static Log log = LogFactory.getLog(ServiceLocator.class);

    static {
        try
        {
            me = new ServiceLocator();
        }
        catch (Exception e)
        {
            log.fatal("Error occurred initializing ServiceLocator");
            e.printStackTrace();
        }
    }

    //~ Constructors ===========================================================

    private ServiceLocator() throws HibernateException, JDBCException
    {}

    //~ Methods ================================================================

    public static Session currentSession() throws PersistenceException
    {
        Session s = (Session) session.get();

        if (s == null)
        {
            s = PersistenceManager.openSession();
            if (log.isDebugEnabled())
            {
                log.debug("Opened hibernate session.");
            }

            session.set(s);
        }

        return s;
    }

    public static void closeSession() throws HibernateException, JDBCException
    {
        Session s = (Session) session.get();
        session.set(null);

        if (s != null)
        {
            if (s.isOpen())
            {
                s.flush();
                s.close();

                if (log.isDebugEnabled())
                {
                    log.debug("Closed hibernate session.");
                }
            }
        }
        else
        {
            log.warn("Hibernate session was inadvertently already closed.");

        }
    }
}
]]>
      </source>
    </section>

    <section name="Create Servlet Filter.">
      <p>
        The servlet Filter is required if you use lazy loading of objects because you need to open a Hibernate sesion, and keeps it open through the view layer. 
        This ensures that each user get's their own Hibernate Session.  ?? Should this be done
        through some sort of SessionValidator?

      </p>
     
        <source>
<![CDATA[        
package com.upstate.cellculture.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.hibernate.Session;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.upstate.cellculture.om.persist.PersistenceException;
import com.upstate.cellculture.om.persist.ServiceLocator;

public class ActionFilter implements Filter
{
    //~ Static fields/initializers =============================================

    //~ Instance fields ========================================================

    /**
     * The <code>Log</code> instance for this class
     */
    private Log log = LogFactory.getLog(ActionFilter.class);
    private FilterConfig filterConfig = null;

    //~ Methods ================================================================

    public void init(FilterConfig filterConfig) throws ServletException
    {
        this.filterConfig = filterConfig;

    }

    /**
     * Destroys the filter.
     */
    public void destroy()
    {
        filterConfig = null;
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException
    {
        // cast to the types I want to use
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        HttpSession session = request.getSession(true);

        Session ses = null;
        boolean sessionCreated = false;

        try
        {
            chain.doFilter(request, response);
        }
        finally
        {
            try
            {
                ServiceLocator.closeSession();
            }
            catch (Exception exc)
            {
                log.error("Error closing hibernate session.", exc);
                exc.printStackTrace();
            }
        }
    }

    public static Session getSession() throws PersistenceException
    {
        try
        {

            return ServiceLocator.currentSession();
        }
        catch (Exception e)
        {
            throw new PersistenceException("Could not find current Hibernate session.", e);
        }

    }
}

]]>
      </source>
    </section>






    <section name="Implementing Manager classes">
        <p>
      To centralize access to the database, we create Manager classes.  Often Manager
      classes are called DAO (Data Access Classes).  Here is an example:
        </p>
        <source>
<![CDATA[
/*
 * Created on Apr 28, 2003
 *
 */
package com.upstate.cellculture.om.persist;
import java.util.List;

import net.sf.hibernate.Query;
import net.sf.hibernate.Session;

import com.upstate.cellculture.om.Technician;
/**
 * @author tmckinney
 *
 * Centralizes all access to the Technicians table
 */
public class TechnicianManager
{
    private static List allTechnicians;
    public static void save(Technician technician) throws PersistenceException
    {
        try
        {

            ServiceLocator.currentSession().save(technician);

        }
        catch (Exception e)
        {
            throw new PersistenceException("Could not save.", e);
        }
    }

    public static Technician retrieveByPK(long technicianId) throws PersistenceException
       {
           try
             {
                 Technician technician= (Technician) ServiceLocator.currentSession().load(Technician.class, new Long(technicianId));
                 return technician;
             }
             catch (Exception e)
             {
                 throw new PersistenceException("Could not retrieve.", e);
             }
       }


    public static List retrieveAllTechnicians() throws PersistenceException
    {
        if (allTechnicians == null)
        {
            try
            {
                Query q = ServiceLocator.currentSession().createQuery("from technician in class " + Technician.class +" order by upper(technician.name)");
                allTechnicians = q.list();
                session.flush();
            }
            catch (Exception e)
            {
                e.printStackTrace();
                throw new PersistenceException(e);
            }
        }
        return allTechnicians;

    }


}

]]>
      </source>
      <p>
          By using this TechnicianManager class, we could feasibly swap out the Hibernate code
          for another OM strategy.  Even better would be to have a TechnicianManager interface
          and a TechicianManagerImpl class.  Possibly loaded via Avalon as a component!
      </p>
    </section>

    <section name="Setup PersitenceException handling">
        <p>
      By catching a generice Persistence Exception that wraps all the
      thrown exceptions we can just catch a single exception and then 
      retrieve what type of exception it is.
        </p>
        <source>
<![CDATA[
package com.upstate.cellculture.om.persist;

import org.apache.commons.lang.exception.NestableException;
/**
 * A general PersistenceException that is thrown by all Manager classes.
 *
 */
public class PersistenceException extends NestableException
{
    //~ Constructors ===========================================================

    /**
     * Constructor for PersistenceException.
     */
    public PersistenceException()
    {
        super();
    }

    /**
     * Constructor for PersistenceException.
     *
     * @param message
     */
    public PersistenceException(String message)
    {
        super(message);
    }

    /**
     * Constructor for PersistenceException.
     *
     * @param message
     * @param cause
     */
    public PersistenceException(String message, Throwable cause)
    {
        super(message, cause);
    }

    /**
     * Constructor for PersistenceException.
     *
     * @param cause
     */
    public PersistenceException(Throwable cause)
    {
        super(cause);
    }

}

]]>
      </source>

    </section>
  </body>
</document>


