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:

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:

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:

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:

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.