Print
Hibernate

What it does?

Hibernate uses factories and hides concrete implementation of interesting classes ( notably Session, SessionFactory and Congiuration ) which makes it difficult to use in picocontainer environment.

nanocontainer-persistence provides constructable alternatives and support classes, allowing you to create your DAOs which will utilize constructor injection and do not have to know how to obtain or dispose hibernate sessions.

Constructable alternatives ( basically wrappers / delegates ) to Session , SessionFactory and Configuration allow easy registration of those components by every scripting system provided by nanocontainer.

Components in detail

ConstructableConfiguration

org.nanocontainer.persistence.hibernate.ConstructableConfiguration inherits from Configuration and provides 4 constructors, which are parameter-identical with configure() methods of Configuration (as you may expect, it calls those methods directly)

SessionFactoryDelegator

org.nanocontainer.persistence.hibernate.SessionFactoryDelegator implements SessionFactory. It can be constructed from Configuration and delegates all method calls to SessionFactory built in constructor. This object can not be used anymore after calling close() ( delegate object will be closed and nullified )

SessionDelegator

org.nanocontainer.persistence.hibernate.SessionDelegator implements Session. It is constructable from session factory. All methods inherited from Session are delegated to real hibernate session obtained from session factory supplied in constructor. All errors arising from hibernate session calls are passed to abstract callback method and rethrown after callback. Concrete implementations are also responsible for obtaining session from session factory and handling of hibernate errors.

FailoverSessionDelegator

org.nanocontainer.persistence.hibernate.SessionDelegator is a concrete implementation of SessionDelegator and provides session invalidation ( clear() and close() ) in case of hibernate error. New hibernate session is obtained transparently.

Lifecycle support

org.nanocontainer.persistence.hibernate.SessionLifecycle and org.nanocontainer.persistence.hibernate.SessionFactoryLifecycle bind Session and SessionFactory components to lifecycle of container. SessionLifecycle flushes and closes hibernate session on container stop() ( for example on end of http request )

Putting it all together

A small example how it might look in web application utilising 3-tier container hierarchy ( application , session and request scoped container as provided by nanowar ). Examples use configuration syntax of XStreamContainerBuilder

Application level container:

nano-application.xml
<container>
    <implementation class="org.nanocontainer.persistence.hibernate.ConstructableConfiguration"/>
    <implementation class="org.nanocontainer.persistence.hibernate.SessionFactoryDelegator"/>
    <implementation class="org.nanocontainer.persistence.hibernate.SessionFactoryLifecycle"/>
</container>

This container registers and creates hibernate configuration from default configuration location and constructs hibernate session factory for it.

It also provides lifecycle component for session factory.

Session level container does not need any specific configuration.

Request level container:

nano-request.xml
<container>
    <implementation class="org.nanocontainer.persistence.hibernate.FailoverSessionDelegator"/>
    <implementation class="org.nanocontainer.persistence.hibernate.SessionLifecycle"/>
    <implementation class="your.cool.dao.receiving.hibernate.session.in.Constructor"/>
</container>

Now your cool DAO class needs to declare hibernate session as constructor parameter, and it will get fres session for every request. It does not have to care about session flushing and closing. It has just to do the job, and leave housekeeping to container:

CoolDao.java
package your.cool.dao;

import org.hibernate.Session;
import org.hibernate.HibernateException
public class CoolDao {
    Session session;
    public CoolDat(Session session) {
         this.session = session;
    }

    Session getSession() {
        return session;
    }


   public void doCoolStuff() throws HibernateException {
        // do you cool stuff here.
   }
}

Pretty easy, isn't it?

Powered by Atlassian Confluence