ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Hibernate for Java SE
Pages: 1, 2, 3

Using the Session

At this point, you could pick up various articles or how-tos for Hibernate and persistence or querying various objects as well as numerous examples on how to use transactions, so I will not go into any detail on those points. Instead, think about what you need to do with the entities and how that affects the Hibernate Session object. Is it possible to use existing business objects or even data access objects? When I set up my data layer, I used Spring and some of the classes it provides to manage connections, transactions, and Sessions. These objects are all defined in XML configuration files with various rules and relationships tightly integrated in Spring. First, my DAO objects are injected into my services via Spring's dependency injection (see Bruce Tate's "Five Things I Love About Spring" for more on dependency injection). Then the services are configured to catch specific DAO exceptions (in an XML config file), which Spring will transact appropriately. While I decided it was too much work to try to integrate Spring into my data loader app, I did make some minor adjustments to my DAO objects so that they could be used outside of my web app.



Let's say I have a method in a PersonDAO that saves a person object. Since my container sets the Hibernate Session up for me, I wouldn't be able to reuse that DAO method outside of the container because it expects a Session object to already exist and be fully configured. Here's what a typical PersonDAO might look like with Session support provided by the Spring container:

import org.springframework.orm.hibernate.HibernateTemplate;
import test.pojos.Person;

public class PersonDAO extends HibernateTemplate {

    public PersonDAO(){}

    public Person save(Person aPerson) {
        if(aPerson != null) super.save(person);
        return person;
    }
}

The above class extends the Spring HibernateTemplate class, which provides all sorts of nice base methods for working with Hibernate. And since HibernateTemplate manages most of the mundane operations, you only have to focus on your specific persistence needs. There should also be proper exception handling, but for this demonstration, the above code will suffice.

Now, to add support for Sessions outside of the container, we only have to make a few minor modifications:

import org.springframework.orm.hibernate.HibernateTemplate;
import net.sf.hibernate.Session;
import test.pojos.Person;

public class PersonDAO extends HibernateTemplate {

    public PersonDAO(){}

    public void setExternalSessionFactory(Session aSession){
        setSessionFactory(session.getSessionFactory());
    }

    public Person save(Person aPerson) {
        if(aPerson != null) super.save(person);
        return person;
    }
}

Since HibernateTemplate extends HibernateAccessor, I'm allowed to set a SessionFactory from any Session object I choose. This is a highly flexible design on the part of the Spring team and makes reuse of existing code much easier.

Now you might not be using Spring and therefore have a completely different approach. Say you don't have fancy Spring dependency injection and you look up your Session object from JNDI like so:

import net.sf.hibernate.Session;

public class PersonDAO {

// This example assumes that there is a Hibernate
// Session object at the following JNDI location
// on a Tomcat 5.5 server:
// java:/comp/env/obj/hibernateSession

    private Session session;

    public PersonDAO(){
        try {
            Context initCtx = new InitialContext();
            Context envCtx = (Context) 
             initCtx.lookup("java:comp/env");
            session = (Session)envCtx.
             lookup("obj/hibernateSession");
        }catch(Exception e) {
            e.printStackTrace();
        }
    }

    public Person save(Person aPerson) {
        if(aPerson != null) session.save(person);
        return person;
    }
}

The above example relies on the application container to make available a Hibernate Session object for its use. The simplest way for use to use this outside of our container would be to just add another constructor that accepts a Session object:

import net.sf.hibernate.Session;

public class PersonDAO {

// This example assumes that there is a Hibernate
// Session object at the following JNDI location
// on a Tomcat 5.5 server:
// java:/comp/env/obj/hibernateSession

    private Session session;

    public PersonDAO(){
        try {
            Context initCtx = new InitialContext();
            Context envCtx = (Context) 
             initCtx.lookup("java:comp/env");
            session = (Session)envCtx.
             lookup("obj/hibernateSession");
        }catch(Exception e) {
            e.printStackTrace();
        }
    }

    public PersonDAO(Session aSession){
        session = aSession;
    }

    public Person save(Person aPerson) {
        if(aPerson != null) session.save(person);
        return person;
    }
}

Obviously we're not handling many exceptions, transaction issues, or the fact that we're even sharing a Session object across many methods, which could cause some concurrency issues depending on how your container or framework handles object instances. However, I think it is clear that the above examples demonstrate that you can reuse a lot of existing data layer code. It just requires a little creative thought. Just make sure that if you do try to use your entities and DAOs outside of your app server, test, test, test!

Conclusion

As you can see, there are some tricks to using your Hibernate entities and DAOs outside of a web container, but it can definitely be done. The biggest challenges are finding the entity mappings and figuring out how to reconfigure, or augment, your existing data access objects (DAOs). When working with the latter, take care to manage your transactions, as you might not have any of your existing business services to rely upon. But in the end, you can have access to all of your entities and the objects used to persist them, which can save a lot of redevelopment time. Good luck!

Jason Lee has been developing web apps for the past ten years and currently is VP of technology at a small startup.


Return to ONJava.com.