December 31, 2007

Maven + Hibernate + Spring fun

Maven can be pain, indeed. Few days ago I put following dependency to my pom.xml:

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.3.1.ga</version>
</dependency>

but the build failed, saying that javax.transaction:jta:jar:1.0.1B cannot be resolved. After some googling I found a solution in a google cache of Dhruba Bandopadhyay's blog. The 1.0.1B can be found in a java.net repository. Actually, the poms of this version are available on ibiblio too, but the jars are missing.

So simply add
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net Maven 2 Repository</name>
<url>http://download.java.net/maven/2/</url>
</repository>

I ran maven again, only to come across

java.lang.NoClassDefFoundError: EDU/oswego/cs/dl/util/concurrent/ConcurrentReaderHashMap
at org.jboss.util.file.ArchiveBrowser.<clinit>(ArchiveBrowser.java:52)

I found an opened bug in hibernate issue tracker from November 07, but it was not fixed yet. After some additional search I found that the required dependency can be found at jboss's maven repository.

<dependencies>
<dependency>
<groupId>oswego-concurrent</groupId>
<artifactId>concurrent</artifactId>
<version>1.3.4</version>
</dependency>
</dependencies>

<repository>
<id>jboss.org</id>
<name>Jboss Maven 2 Repository</name>
<url>http://repository.jboss.org/maven2/</url>
</repository>

But this piece of configuration just yielded another exception, this time it was a NoSuchMethodException, complaining about ClassValidator.<init> method missing. Although I saw the missing constructor in the hibernate jars, I was still getting this error. I spent hours searching the web, only to find many people having the same problem and trying various suggestions, but none of them worked.


The solution came today, when I read this post from Lukas Krecan. In his code I found the correct dependecies

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.3.1.ga</version>
</dependency>
<dependency>
<groupId>concurrent</groupId>
<artifactId>concurrent</artifactId>
<version>1.3.4</version>
</dependency>

and the correct Spring + JPA initialization

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="Spring.Persistence" />
<property name="dataSource" ref="dataSource" />
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

In META-INF/persistence.xml put:

<?xml version="1.0" encoding="UTF-8"?>

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">

<persistence-unit name="Spring.Persistence" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
</persistence-unit>

</persistence>

Thank you Lukas.