Tuesday, June 15, 2010

Setting up JPA 2.0 Out-Of-Container

Hi, today I would like to explain how to set up the JPA 2.0 Out of container.
I'll use MySQL as a back-end database And hibernate 3.5 as a persistence provider.

First of all some introduction (really short).

JEE 6 brought us a new persistent standard called JPA 2(Java Persistence Architecture) which is a natural evolution of JPA available from JEE(5).

A popular ORM tool Hibernate 3.5.x provides an implementation of the JPA 2 specification.
While JPA 2.0 is mostly efficient in a managed environment (usually inside application server), sometimes we would just like to come up with a simple use case:
we would like to write a class with a "main" method, configure the JPA 2.0 environment and interact with our relational database management server.
Such a configuration is called "out-of-container".

"Out-of-container" (later OOC for the sake of brevity) configuration has some drawbacks when compared to the "standard" (managed) invocation mode.
- we can't use JTA (transaction control)
- we have to define our domain classes explicitly in the file called "persistence.xml" which is a part of JPA/JPA 2 standard

On the other hand we gain simplicity, fast startup, eliminate the dependency on application server. This makes OOC an attractive solution for unit testing, developing the domain model objects, etc.

So how would we set up a working OOC environment?

First of all, we will need a RDBMS - I'll use MySQL for that.

Next, I'll download Hibernate. The latest stable version at this moment is 3.5.2, so I'll download it from the official Hibernate site
Installing MySQL should not be a problem so I won't cover this here.
I assume that the data base is running and proceed with java related stuff.

First of all we'll create the simple java project in the IDE and put the following list of dependent jars:

- antlr-2.7.6.jar
- commons-collections-3.1.jar
- dom4j-1.6.1.jar
- hibernate-jpa-2.0-api-1.0.0.Final.jar
- hibernate3.jar
- javaassist-3.9.0.GA.jar
- jta-1.1.jar

All of them can be found in the downloaded hibernate distribution archive
I also added the latest versions of the slf4j - logging system:
- slf4j-api-1.6.0.jar
- slf4j-simple-1.6.0.jar
These jars I've downloaded manually here

The last jar we will need is the MySQL jdbc driver. The connector-j can be downloaded from the manufacturer's site here
So we add the
- mysql-connector-java-5.1.12-bin.jar
to the list of our dependencies

Now when all the dependent jars are present we will create a special file called persistence.xml and put there all the information about connection configuration.
According to the JPA standards it should be placed into the META-INF folder of your project like this:
META-INF/persistence.xml

Here is the sample file:





The xml contains definitions of persistence unit, we call it 'testPersistenceUnit' (remember this name, we will use it later) and various configuration stuff (see the comment in the xml file)



Now we'll create a sample domain-object. This is a fairly simple POJO with JPA annotations. The class "User" will have id, first name and last name. Hence the code:



Please, notice that the annotations declared in the 'imports' section are from javax.persistence (JPA 2 annotations ) and not Hibernate specific.
Another important thing is the mapping itself, each property will be mapped to the corresponding column in the database. And the entity itself will be mapped to the table "USERS" (we will create everything we need in the data base later)
Also note, that this class has been listed in the persistence.xml file

And now we will create the last part of the puzzle - the class responsible for initialization of OOC and running the sample JPA code.



Again, I've tried to provide short explanations in the code.

Now this code can be run for the first time. Assuming that the database doesn't have a table "USERS" and in the persistence.xml database/username/password properties are set and the property hibernate.hbm2ddl.auto is defined to be "create":



we will run the program for the first time:
The output will be a lot of configuration related stuff as well as the important line:

Hibernate: insert into USERS (FIRST_NAME, LAST_NAME, id) values (?, ?, ?)

Now the table "Users" has been created and the new row has been inserted into the db

Each time you run the program, the table will be dropped at the very beginning, created from scratch and filled with the sample data.

I hope it was a helpful tutorial, comments are welcome :)
Thanks a lot for attention
Mark Bramnik