Hibernate Session Management and Implementing the DAOs"

From Documentation
m (Redirected page to ZK Essentials)
 
Line 1: Line 1:
 +
#REDIRECT [[ZK Essentials]]
 +
 
{{ZKEssentialsPageHeader}}
 
{{ZKEssentialsPageHeader}}
  

Latest revision as of 00:05, 29 March 2013

Redirect to:

Stop.png This article is out of date, please refer to http://books.zkoss.org/zkessentials-book/master/ for more up to date information.


As discussed earlier, we do not use neither an EJB3 container nor Spring. Therefore, we need to manage the session ourselves. This involves building a SessionFactory object when the application loads, closing it when the application ends and manually opening and closing sessions when required.

The SessionFactory and the HibernateUtil

A common pattern in Hibernate is to make use of a HibernateUtil. This is a class which provides functionality to build and access our SessionFactory. The following code compromises our HibernateUtil:

public class StoreHibernateUtil {
    private static final SessionFactory sessionFactory;

    static {
        try {

            // Create the SessionFactory from standard (hibernate.cfg.xml) 
            // config file.
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Log the exception. 
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static Session openSession() {
        return sessionFactory.openSession();
    }
}


In this class, the SessionFactory is built statically upon first accessing the object and then provides static utility methods to access the SessionFactory and then open a new Session.

Please note that there is no need to build the SessionFactory when the application loads or close it when the application terminates. To do so, we implement two ZK interfaces, WebAppInit and WebAppCleanup and specify the implementing class in the zk.xml file:


public class HibernateListeners implements WebAppInit, WebAppCleanup {

    public void init(WebApp webapp) throws Exception {
        //initialize Hibernate
        StoreHibernateUtil.getSessionFactory();
    }

    public void cleanup(WebApp webapp) throws Exception {
        //Close Hibernate
        StoreHibernateUtil.getSessionFactory().close();
    }

}
<zk>
    <listener>
        <listener-class>demo.model.HibernateListeners</listener-class>
   </listener>
</zk>

In this case, we named our class HibernateListeners and made sure that the SessionFactory was built on initialization of the web application and closed in the cleanup method.

This initializes and closes Hibernate now and we need to make use of it in the DAOs.

Re-implementing the DAOs using Hibernate

In this section we are going to explore the general usage of Hibernate in our DAOs for the majority of use cases. We open and close one when performing any database interactions. Hibernate is centered around Session and Transaction concept where a session can have many transactions, commiting and rolling them back from the session as needed. In this example, there will only be one Transaction per session due to the simplicity of the use case. However, it is entirely possible to have a session which span all the transactions of a user. For more information on Sessions and Transactions in Hibernate please click here.

Let’s take a simple use case for retrieving all the available Products found in ProductDAO.java:


public List<Product> findAll(){
		//return new ArrayList<Product>(dbModel.values());
            Session session = StoreHibernateUtil.openSession();
            Query query = session.createQuery("from products");
            List<Product> products = query.list();

            session.close();
            return products;
}

In this code snippet, we utilize our HibernateUtil to open a new session at line 3 and then create a query. The query is written in HQL (Hibernate Query Language) retrieving all the rows from the table products. For more information on HQL please click here. Once we create the Query object, we can use its listed method to retrieve the List of products, close the session and then return.

At the same time sometimes we need to retrieve all available Products. This means we need to retrieve all the Products where available is equal to true. In our example, we do this by creating a Criteria object:


public List<Product> findAllAvailable(){
            Session session = StoreHibernateUtil.openSession();
            Transaction t = session.beginTransaction();

            Criteria criteria = session.createCriteria(Product.class).add(Restrictions.eq("available", true));
            List<Product> products = criteria.list();
            t.commit();
            session.close();

            return products;
}


The snippet follows the same session management strategy, however, this time we create a Criteria object to add a restriction that "available" must be true. Then we can use the method criteria.list() to retrieve a list of products which are available.

The retrieval methods in each DAO follow a similar strategy so finally let’s take a look at the add method of the OrderDAO which persists an Order.

public void add(Order order){

            Session session = StoreHibernateUtil.openSession();
            Transaction t = session.beginTransaction();

            session.persist(order);
            t.commit();

            session.close();
}

We see that the Session management strategy is exactly the same, however, now we use the session’s persist function to add the Order object to the session, then we commit the transaction and close the session. This will then add the Order object to the relative table.



Last Update : 2013/03/29

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.