Hibernate for Java SE

By now it's easy to see that Hibernate is quickly becoming a popular (if
not the most popular) O/R mapper/data integration framework for
J2EE. It offers a developer clear, concise, and powerful tools for
working with relational databases in the enterprise. But what if
you need outside access to those entities that are wrapped up in
your J2EE web application? Do you develop separate, yet identical,
entities to access your data? Or do you write additional web
components to manage the internal access to your data?

At some point, these questions are bound to come up, and for me,
it was when my company needed to upload records into our database
from multiple vendors in multiple file formats. I thought about the
approach I had always taken before, which was to write shell and
SQL scripts (and even stored procedures) to upload the data. But
because our data model is quite complex, I decided to leverage what
existing entities, Spring DAOs, and services outside of our web app
I could and develop a custom J2SE command-line data loader.

The Big Question: Should You?

Much of the documentation and many of the examples that exist for Hibernate today all revolve around using it in a container. Whether it's for a web app or in-house "fat app," there's usually a container involved. There's good reason for this. Containers are designed to include support for all sorts of features, such as transactions, threading, and security. Nowadays, these are required tools for developing mid-size and enterprise applications. But what should you do when you need access to your entities objects outside your container? Should you use your existing infrastructure and code, or come at the problem from a different angle, possibly with a different language altogether? Of course, there is no right answer, and for the rest of this article I will explain my approach, which was to reuse my existing entities/POJOs outside of my Spring container.

Scripting languages such as Perl, Python, Ruby, or even Tcl
(yes, I've done this before) seem to have some advantages at
first. A lot of the time, they're quick to hack up, easy to get
initial results, and can bypass a lot of the underlying complexity
of Hibernate. It's possible in just a few lines to make a
connection to a database, select some results, and print them out to the
screen or some log file. However, depending on your data model,
things can (and usually do) get quite complicated. Say you have a
person table that has a foreign key to an address table, and while
inserting data, the address doesn't insert properly, which causes
the person to not insert as well: a typical transactional issue. One
could argue that it's not too hard to account for this in your
scripting language du jour, just like in your main application. But
the question remains: why should you? If this logic already exists
in your application, why code it again? And since this probably
won't be the only case, you will be duplicating work and logic and
thusly introducing the possibility of errors, as well.

Some people, however, will see this as OK and use whatever tool
they feel is best for that job. Maybe you already have some sort of
separate infrastructure for reasons outside of programming. Maybe you
upload and test your data on a separate database and after it passes
various tests, it is then migrated to a production database. Or maybe
your database maintenance is outsourced and you just send the files to
your partner company and they take of the issues. In the end, there
could be many other reasons not to use your existing Hibernate data
layer--none of them right or wrong. But if you can and will use
your existing code base outside of your app, then read on. I might
be able to uncover a few tips and save you a few headaches in the
process.

Configuration

Once you have decided that it is OK to use your existing
Hibernate objects outside of your container, then the first thing
you'll have to do is to manage all of the configuration yourself. The
approach I will take for the rest of the article is via a
command line, standalone Java app. Since you probably already have
a Hibernate XML configuration file set up, you already know what
parameters are required, such as JNDI DataSource name, entity
mapping files, and miscellaneous properties for logging SQL.
If you decide to use a command-line application, you will have to
figure out how to parse the XML file and add it to your new
configuration. While parsing an XML document is not impossible, it
can sometimes be a little side project in itself. Thus, I recommend
using a regular properties file. A properties file is pretty
straightforward and fairly easy to load up and get values from. The
following is an example of a minimal set of properties needed to
configure Hibernate (sans any entity mappings):

As you can see, the above properties specify the database dialect,
the JDBC driver class, database server name, user name and
password, and whether or not to use query substitutions. Once you
have defined these and saved them in a hibernate.properties
file (which should reside in your classpath, by the way), they are
fairly easy to load up and hand off to the Hibernate
Configuration object.