Monday, April 21, 2008

Converting Daos from Hibernate to JPA

Over the weekend I converted the Daos of my pet project jRecruiter from Hibernate to the Java Persistence API (JPA) using Hibernate as persistence provider. The project is using the latest Spring version (2.5.3) and I also incorporated Spring's latest annotation features. This allowed me to remove all the Dao-related Spring bean declarations in my context.xml file. The actual conversion from pure Hibernate to JPA was quite straight forward. I was struggling a bit with the Spring configuration of the entityManagerFactory but got it to work eventually.

Here is my Spring context file with the JPA setup.































${hibernate.dialect}
true 'Y', false 'N'
true
org.hibernate.cache.EhCacheProvider
true
true









The modifications to the daos itself were rather modest. One difference I noticed is that executing a query using query.getSingleResult(); throws a NoResultException. I prefer returning null - therefore I had to do the following:


try {
user = (User) query.getSingleResult();
} catch(NoResultException e) {
user = null;
}


Also, the Dao classes are annotated with @Repository e.g.:


...
@Repository("userDao")
public class UserDaoJpa extends GenericDaoJpa<>
implements UserDao {
...


Also, I use some of the new Spring features that allow me to get rid of quite a bit of XML:







Using context:component-scan Spring will auto-detect my daos and registered them with the context without any XML necessary. I think this is kind of neat especially for smaller projects.

Lastly, in case you need to access Hibernatenate's SessionFactory directly:

Session session = (Session)entityManager.getDelegate();

2 comments:

Unknown said...

I've always been puzzled by the NoResultException thing. I can understand that you want to be consistent (a la NonUniqueResultException). So now we're using exceptions for code flow logic? ugh. I suppose the other thing that can be done is query/count the results then call this method, but it seems to defeat the purpose...

afsina said...

usage NoResultException may not be incorrect (even mostly useless), but API could be improved as defining a single or no result return method. like getSingleOrNoResult() or such. Of course it is such a shame that neither Spring nor Hibernate utilizes Generics. talk about "modern" frameworks.