JPA persistence within JBoss 5 (not using JTA)

I’ve recently been working on a task involving JPA persistence within a servlet running in JBoss 5.  My servlet hasn’t been built using EJB, so at this stage I haven’t been using the JTA to manage my database transactions. 

People more experienced than me assure me that it is good practice to use EJB, and use the JTA to manage transactions, as it will do a much better job than I ever could, so this will be a task for the near future.

However, in the meantime, I’m not using JTA.  I’m using the Hibernate implementation of JPA provided within JBoss.  The first thing you need to do to not use JTA is to set the transaction-type of the persistence-unit to RESOURCE_LOCAL.  You then need to specify a non-jta-data-source within persistence.xml.

You define your data source within an xml file, and then add a module to the jboss-app.xml file within your servlet which references the data source file as a service.

I was using the H2 database.  I found that I had to copy the h2*.jar file into JBOSS_HOME/server/default/lib in order for JBoss to find the jdbc driver classes.

To manage transactions, I found I had to follow the following workflow:

get entity manager from factory -> begin transaction -> do work -> commit -> close the entity manager.

And thats it.  Hopefully further posts to follow regarding using EJB and JTA.

Connecting to Derby network server with JPA

I’ve already posted about connecting to a Derby database via JPA.  That was using an Derby database embedded in the same VM as the application.  Now we will address the more common case, where the database is provided by a network server.  Using the Apache Getting Started guide, I set up the Derby network server.  It is available to handle database requests on port 1527.

To update my application to make requests to it, I updated my persistence.xml file to the following:

<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/db1;create=true" />
<property name="javax.persistence.jdbc.user" value="" />
<property name="javax.persistence.jdbc.password" value="" />

<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/>
<property name="hibernate.show_sql" value="true" />
<property name="" value="create" />

The changes in the file are to the URL via which I am connecting to the database, and the driver class I am using to make the connection. Where I was using an EmbeddedDriver, I’m now using the ClientDriver.

Using JPA within Eclipse RCP

OK, so I have an RCP application which is using JPA to persist some data model objects to a database. I am using the Hibernate implementation of JPA, and I am using a H2 database.

In order to bundle up my dependencies on Hibernate and H2 in a nice RCP way, I have put all the Hibernate libraries into a plug-in called org.hibernate, and all my H2 libraries into a plug-in called org.h2. I can then list these as dependencies within the manifest of my plug-in projects.

Some of the JPA tutorials I looked at when getting started were:

When I had created my JPA persistence classes, I thought I’d write some unit tests to ensure that they were working as expected. Everything compiles, but when I run my unit tests as JUnit Plug-in tests, I get the following error:

javax.persistence.PersistenceException: No Persistence provider for EntityManager

Uh-oh, this looks like some kind of class loading issue, right? After a search online, I came across the suggestion that the Eclipse buddy class loading mechanism might be able to help.A useful article on it can be found here:

In my org.hibernate plug-in, I updated the manifest to include the line “Eclipse-BuddyPolicy: registered”. This means that, when at runtime the org.hibernate bundle is looking for the persistence unit declared in your persistence.xml file, it will consult all dependent bundles that explicitly register themselves as buddies to it. In the manifest of my client plug-in, I added the line “Eclipse-RegisterBuddy: org.hibernate”, in order to register it as a buddy.

Now Hibernate is able to find my persistence unit, and all of the classes defined within it, at runtime, and everything runs fine.