0

I'm trying to write JUnit Tests for an application that uses JPA with a Hibernate provider.

The way the JPA Context Beans are instantiated in the application is through JNDI names, that are defined in the Server Resources (Tomcat). I can't have that when testing with JUnit, so I have to provide a different context for JPA that is suited to run the tests.

The main problem when writing JUnit tests for an application that was written to be packaged in a WAR and run in a "Server Container", is that you have to replace the javaee-api jars with actual implementations of the APIs, I understand that part.

I use :

  @ContextConfiguration(locations = { "classpath:context-config-test.xml" })

to tell Spring to setup a different context configuration XML for the Test.

Now, to the real problem : I'm trying to setup an EMF (EntitiManagerFactory) that uses Hibernate as the "Persistence Provider". The way the "normal context" does it is via this :

<bean id="MyEntityManagerFactory"
   class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="my_pu_name" />
    <property name="persistenceXmlLocation" value="classpath:jpa/persistence.xml" />
</bean>

and then in jpa/persistence.xml :

<!-- spring with jta and entity manager factory -->
<persistence-unit name="my_pu_name" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>jdbc/my_jndi_db_name</jta-data-source>
    <properties>
       ....
    </properties>
</persistence-unit>

And it works fine.

Now the way I'm trying to do it for the "Test Context" is faily close, like this :

<bean id="myEntityManagerFactory"
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="myDatasource"/>
    <property name="persistenceUnitName" value="my_pu_name_test" />
    <property name="persistenceXmlLocation" value="classpath:jpa/persistence-test.xml" />
</bean>

Then in jpa/persistence-test.xml :

<persistence-unit name="my_pu_name_test" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <exclude-unlisted-classes/>
    <properties>
       .....
    </properties>
</persistence-unit>

... it seems OK, but I get the exception :

java.lang.IllegalStateException: Failed to load ApplicationContext Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myEntityManagerFactory' defined in class path resource [spring/beans-test.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax.persistence.spi.PersistenceUnitInfo.getValidationMode()Ljavax/persistence/ValidationMode;

I looked around a while, changed the Maven Dependencies to point to Hibernate-Core, which is an Implemenatation of JPA, checked the scopes were OK, and such things... but nothing worked. After a while looking around I found that

    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

was maybe better to use than

    <provider>org.hibernate.ejb.HibernatePersistence</provider>

and I thought I found the problem but that didn't fix it...

So I really don't know what else to do now...

Here is the Hibernate-Dependencies i use in my POM :

    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.0-api</artifactId>
        <version>1.0.1.Final</version>
        <scope>runtime</scope>
        <exclusions>

            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.version}</version>
        <exclusions>
            <!-- slf4j already contained in Tomcat -->
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
        <exclusions>
            <!-- slf4j already contained in Tomcat -->
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

I also tried commenting the first one but didn't work.

I would really appreciate any help or pointers on this issue...

Thanks and have a nice day :)

Genku
  • 31
  • 8

1 Answers1

0

So the way I fixed it, since nothing seemed to work on the Maven side of things (no scope I put changed anything, javaee-api was always resolved in the classpath before hibernate-jpa) I downloaded and added the jars in the classpath of my JUnit test manually, putting them before the Maven Dependencies... it's not pretty but it does the trick.

Genku
  • 31
  • 8