This blog for Hibernate Generic DAO Project has been moved to WordPress http://hibernategenericdao.wordpress.com/. Bye bye Blogger!

Saturday, June 12, 2010

Configuring Hibernate Generic DAO with JPA

Version 0.5.0 introduced JPA to the "Hibernate" Generic DAO. Version 0.5.1 added a a JPAAnnotationMetadataUtil instance that makes simple non-Hibernate JPA configuration a bit simpler. Future versions willhopefully provide full out-of-the-box support for all JPA 2.0 providers. Until then, this post will explain how to configure Hibernate Generic DAO with JPA 1.0. (Although I hear some people have gotten it to work with 2.0 http://groups.google.com/group/java-generic-dao/browse_thread/thread/a3e792d989b55bb3)


There is an example configuration using Spring and Hibernate JPA in our SVN repo. You can download or browse the source online here: http://code.google.com/p/hibernate-generic-dao/source/browse/#svn/tags/0.5.1/sample/jpa-hibernate-maven%3Fstate%3Dclosed.


Let's get started with a diagram...


In the above diagram each box represents a singleton instance of a class (except EntityManager). These are all you need to know to set up the framework in your project. Let's take a look at the parts:


JPASearchProcessor: You will need one singleton instance of the JPASearchProcessor class for each persistence unit in your project. (Most projects have only one persistence unit and thus only one JPASearchProcessor.) The JPASearchProcessor has only one dependency, it must have an instance of MetadataUtil passed into its constructor.


MetadataUtil: Again you will need one singleton instance of MetadataUtil per persistence unit. The MetadataUtil is used to inform the framework of the structure and relationships in your data model.


While there is only one implementation of JPASearchProcessor, Hibernate Generic DAO ships with two build-in implementations of MetadataUtil. The first implementation that comes with the framework is HibernateMetadataUtil. HibernateMetadataUtil can only be used with Hibernate's JPA implementation. The second is JPAAnnotationMetadataUtil. This is a beta implementation that looks at the JPA annotations on Java classes to determine the data model. It should theoretically work with any JPA 1.0 implementation, but it has only been tested on some basic data models. If neither of these is sufficient for your needs, you can code your own implementation of the MetadataUtil interface. [In fact if someone wants to implement one using JPA 2.0's metadata model, that would be a major contribution to the project, allowing us to fully support any JPA 2.0 implementation out of the box.]


In our sample project in SVN we use Spring framework to create these two singletons and wire them together. In this case we are using the HibernateMetadataUtil class. This requires a reference to the Hibernate EntityManagerFactory which should be configured elsewhere with your Hibernate JPA configuration. Here is a snippet from the applicationContext.xml that show these two singletons.


<bean id="searchProcessor" class="com.trg.search.jpa.JPASearchProcessor">

<constructor-arg ref="metadataUtil" />

</bean>


<bean id="metadataUtil" class="com.trg.search.jpa.hibernate.HibernateMetadataUtil"

factory-method="getInstanceForEntityManagerFactory">

<constructor-arg ref="entityManagerFactory" />

</bean>


An alternative configuration that uses JPAAnnotationMetadataUtil would be as follows. JPAAnnotationMetadataUtil does not require any configuration options. It just looks for annotated classes on the classpath.


<bean id="searchProcessor" class="com.trg.search.jpa.JPASearchProcessor">

<constructor-arg ref="metadataUtil" />

</bean>


<bean id="metadataUtil" class="com.trg.search.jpa.JPAAnnotationMetadataUtil"/>



Diagram showing the dependencies for the two different MetadataUtil implementations. HibernateMetadataUtil requires a reference to the HibernateEntityManager. JPAAnnotationMetadataUtil stands alone.


Now that we have that set up, we turn to our individual DAOs. Each one requires two things, (1) a reference to the JPASearchProcessor singleton and (2) an EntityManager (not a singleton). You can decide how the DAO will get an EntityManager when it needs it by overriding the getEntityManager() method of GenericDAOImpl or GeneralDAOImpl. In the case of our example, we rely on Spring framework to inject the current EntityManager into our DAOs via the @PersistenceContext annotation on the setEntityManager() method. We are also having spring automatically set our JPASearchProcessor via an @Autowired annotation. In order to make both of these apply to all our DAOs, we have a base class that all of them extend. This is not necessary, but in this case it’s convenient. Here’s the code for the BaseDAO class:


@Repository

public class BaseDAO<T, ID extends Serializable> extends GenericDAOImpl<T, ID> {

@Override

@PersistenceContext

public void setEntityManager(EntityManager entityManager) {

super.setEntityManager(entityManager);

}

@Override

@Autowired

public void setSearchProcessor(JPASearchProcessor searchProcessor) {

super.setSearchProcessor(searchProcessor);

}

}


We took a similar strategy for the GeneralDAO (See DecoratedGeneralDAOImpl in the sample code).


So that’s basically all there is to know about configuring the framework for use with JPA. For other installation information start at this wiki page (http://code.google.com/p/hibernate-generic-dao/wiki/InstallationAndConfiguration).


Best of luck. Our forum is found at http://groups.google.com/group/java-generic-dao. And if anyone wants to contribute to features of this open source project or the JPA 2.0 updates, let me know.

Thursday, March 11, 2010

Version 0.5.1 Released with a number of bug fixes

Tonight I pushed a new build (0.5.1) to the Maven repository. This has been a long time in coming, and consists primarily of bug fixes. (For a list of all issues fixed in this release see the Road Map).

There is one important change in the Generic DAO interface, however. We changed the signature of the search() and searchUnique() methods.

Old Signature:

List<ENTITY_CLASS> search(Search search);
ENTITY_CLASS searchUnique(Search search);

New Signature:

<EXPECTED_TYPE> List<EXPECTED_TYPE> search(Search search);
<EXPECTED_TYPE> EXPECTED_TYPE searchUnique(Search search);

The old signature assumed that every search would return the root entity type, but with the Fields and result mode options on the Search, this is not always so. The old solution for this was to have two additional methods: searchGeneric and searchUniqueGeneric which returned List<?> and Object types respectively. The new approach eliminates the need for these confusing methods.

If you are unfamiliar with this sort of generic method signature, what it does is determine the return type of the method based on the context from which it is called, effectively reducing the need for explicit casting. (Here's a more in-depth description.)

For example, if we're using the RESULT_ARRAY result mode...

Old way:

List<Object[]> results = (List<Object[]>) dao.searchGeneric(search);

New way:

List<Object[]> results = dao.search(search);

With the new method signatures, the Java compiler is able to infer from the type of the "results" variable that search() will return a list of type List<Object[]>. There is no longer a need to explicitly cast it in most cases.

In addition to all this, we added a new (Beta) implementation of MetadataUtil that uses JPA Annotations to determine the persistence meta model. The implication of this is that the framework should be able to be used, out of the box, with other JPA providers like OpenJPA, TopLink, etc. I hope to post more on just how to configure this when I have time.