I have been using the hibernate3-maven-plugin for some time with a good deal of success in unit testing my data access layers through dbunit. I always separate my data access into a separate module, called data-services, for many reasons. Mostly so I can separate my testing to just database integration testing, and not unit testing in the test phase of maven. First, I create the hibernate3-maven-plugin declaration:


org.codehaus.mojo
hibernate3-maven-plugin
2.2

hbm2hbmxml
target/classes

jpaconfiguration
ApplicationEntityManager
true
${maven.test.skip}
src/test/resources/database.properties

hbm2ddl
process-test-resources

hbm2ddl

com.h2database
h2
${h2.version}

Notice the hbm2ddl execution phase is set to process-test-resources which is when the ddl is created. My database.properties to seed a file based H2 Database:

hibernate.connection.username=sa
hibernate.connection.password=
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.connection.url=jdbc:h2:file:target/h2/testdb;REFERENTIAL_INTEGRITY=FALSE
hibernate.connection.driver_class=org.h2.Driver

I also wanted all my tests to run in the integration-test phase, not the test phase


org.apache.maven.plugins
maven-surefire-plugin
...

surefire-unittest
test

**/*Test.java

none

surefire-it
integration-test

test

none

**/*Test.java

When I execute my normal “mvn clean verify -e”, I get the following trace:

[myproject] DEBUG [main] Ejb3Configuration.configure(312) | Processing PersistenceUnitInfo [
name: ApplicationEntityManager
persistence provider classname: null
classloader: sun.misc.Launcher$AppClassLoader@11b86e7
Temporary classloader: org.springframework.instrument.classloading.SimpleThrowawayClassLoader@11db6bb
excludeUnlistedClasses: false
JTA datasource: null
Non JTA datasource: org.apache.commons.dbcp.BasicDataSource@1c7e2da
Transaction type: RESOURCE_LOCAL
PU root URL: file:/C:/opt/projects/grd/trunk/data-services/target/classes/

I plan on creating another post to detail my JUnit and TestNG DBUnit testing. For this post, I really just want to focus on the error in the hibernate3-maven-plugin. I have 21 tests run successfully:

Results :
Tests run: 21, Failures: 0, Errors: 0, Skipped: 0

What I then wanted to do was integrate Cobertura Code Coverage into this module. I first added just a generic plugin delcaration:


org.codehaus.mojo
cobertura-maven-plugin

com.baselogic.ignore.*

com/baselogic/**/*Test.class

85
85
true

clean
<!--<goal>check</goal>-->

net.sourceforge.cobertura
cobertura
1.9rc1

Notice I commented out the check as I did not want to fail the build, I wanted to allow lower numbers so I could generate the site documentation with these numbers. When I run “mvn site -e”, I get this error trying creating the ApplicationEntityManager stating a class or package was not found:

[INFO] [hibernate3:hbm2ddl {execution: hbm2ddl}]
...
[myproject] DEBUG [main] Ejb3Configuration.configure(209) | Look up for persistence unit: ApplicationEntityManager
[myproject] DEBUG [main] DTDEntityResolver.resolveEntity(64) | trying to resolve system-id [http://java.sun.com/xml/ns/p
ersistence/persistence_1_0.xsd]
[myproject] DEBUG [main] EJB3DTDEntityResolver.resolveEntity(49) | recognized EJB3 ORM namespace; attempting to resolve
on classpath under org/hibernate/ejb
[myproject] DEBUG [main] EJB3DTDEntityResolver.resolveEntity(58) | located [http://java.sun.com/xml/ns/persistence/persi
stence_1_0.xsd] in classpath
[myproject] DEBUG [main] Ejb3Configuration.getDetectedArtifacts(562) | Detect class: true; detect hbm: true
[myproject] DEBUG [main] AbstractJarVisitor.unqualify(116) | Searching mapped entities in jar/par: file:/C:/opt/projects
/grd/trunk/data-services/target/generated-classes/cobertura/
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.dao.BaseDao
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.dao.jpa.BaseDaoJpaImpl$1
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.dao.jpa.BaseDaoJpaImpl
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.domain.IdentifiedObject
[myproject] DEBUG [main] AbstractJarVisitor.executeJavaElementFilter(213) | Java element filter matched for com.baselogi
c.domain.IdentifiedObject
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.domain.User
[myproject] DEBUG [main] AbstractJarVisitor.executeJavaElementFilter(213) | Java element filter matched for com.baselogi
c.domain.User
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.domain.UserNotFoundException
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.service.impl.UserManagerImpl
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.baselogic.service.UserManager
[myproject] DEBUG [main] AbstractJarVisitor.addElement(162) | Filtering: com.fedex.ground.configuration.DataSourceFactor
y
[myproject] DEBUG [main] Ejb3Configuration.getDetectedArtifacts(562) | Detect class: true; detect hbm: true
[myproject] DEBUG [main] Ejb3Configuration.configure(158) | Creating Factory: ApplicationEntityManager
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] [PersistenceUnit: ApplicationEntityManager] class or package not found
com.baselogic.domain.IdentifiedObject
[INFO] ------------------------------------------------------------------------
[INFO] Trace
javax.persistence.PersistenceException: [PersistenceUnit: ApplicationEntityManager] class or package not found
        at org.hibernate.ejb.Ejb3Configuration.addNamedAnnotatedClasses(Ejb3Configuration.java:1093)
        at org.hibernate.ejb.Ejb3Configuration.addClassesToSessionFactory(Ejb3Configuration.java:871)
        at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:758)
        at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:191)
        at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:253)
        at org.codehaus.mojo.hibernate3.configuration.JPAComponentConfiguration.createConfiguration(JPAComponentConfigur
ation.java:28)
        at org.codehaus.mojo.hibernate3.configuration.AbstractComponentConfiguration.getConfiguration(AbstractComponentC
onfiguration.java:51)
        at org.codehaus.mojo.hibernate3.exporter.Hbm2DDLExporterMojo.doExecute(Hbm2DDLExporterMojo.java:87)
        at org.codehaus.mojo.hibernate3.HibernateExporterMojo.execute(HibernateExporterMojo.java:152)
        at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:453)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:559)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:50
0)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.forkProjectLifecycle(DefaultLifecycleExecutor.java:925)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.forkLifecycle(DefaultLifecycleExecutor.java:768)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:550)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:50
0)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:479)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.jav
a:331)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:292)
        at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:301)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
        at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
        at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
        at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: java.lang.ClassNotFoundException: com.baselogic.domain.IdentifiedObject
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at org.codehaus.classworlds.RealmClassLoader.loadClassDirect(RealmClassLoader.java:195)
        at org.codehaus.classworlds.DefaultClassRealm.loadClass(DefaultClassRealm.java:255)
        at org.codehaus.classworlds.DefaultClassRealm.loadClass(DefaultClassRealm.java:274)
        at org.codehaus.classworlds.RealmClassLoader.loadClass(RealmClassLoader.java:214)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:247)
        at org.hibernate.util.ReflectHelper.classForName(ReflectHelper.java:135)
        at org.hibernate.ejb.Ejb3Configuration.classForName(Ejb3Configuration.java:1009)
        at org.hibernate.ejb.Ejb3Configuration.addNamedAnnotatedClasses(Ejb3Configuration.java:1081)
        ... 30 more

I first started looking for the missing class file. I found 2. One in ~target/classes/**/IdentifiedObject.class and another one in ~target/cobertura/**/IdentifiedObject.class. The class was not missing, but it appeared that the hibernate3 plugin was not finding the correct classpath when running these tests instrumented with Cobertura. Remember, the tests run without Cobertura. I wanted to test to make sure Cobertura was running all, so in the above plugin deplaration, Iuncommented the check section and re-ran “mvn clean verify -e” to find that Cobertura was indeed running successfully, and failing the build:

[INFO] [cobertura:check {execution: default}]
Cobertura: Loaded information on 11 classes.
...
Project failed check. Total branch coverage rate of 55.8% is below 85.0%
Project failed check. Total line coverage rate of 74.6% is below 85.0%
...
[INFO] Coverage check failed. See messages above.
[INFO] ------------------------------------------------------------------------

This tells me that Cobertura is instrumenting my DBUnit code, and my tests are running against my H2 file database, but there is not enough code coverage for my checked limits. This at least verifies that Cobertura works. After quite a bit of trial and error, I tried to change the phase in which the hibernate3 plugin was getting executed. I changed from process-test-resources and moved the execute further down the lifecycle to package. Now, when I can “mvn site -e”, I generate my site documentation successfully, as well as get my Cobertura report So now, I wanted to see the effect this change would have on my normal build life cycle, so I re-ran “mvn clean verify -e”. I was faced with more frustration, as now, my plugin was not running in the correct life cycle and all my dbunit test inserts where failing:

[myproject] DEBUG [main] AbstractHibernateTest.prepareDataSet(101) | Invoked prepareDataSet()
prepareSettings called
org.dbunit.dataset.NoSuchTableException: app_user
at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:279)

I have seen this error before and knew that my database was not created by the hibernate3 plugin. I decided to add a property to switch which phase the plugin would get executed. I added a default property process-test-resources to my pom’s … section. I then changed the hibernate3-maven-plugin phase from package to ${hibernate3.execute.phase} Now I needed to create a new profile jsut to switch this phased execution for my site:


lazy-hibernate3
package

Now I could easily use “mvn site -Plazy-hibernate3 -e” to lazily execute my hibernate3-maven-plugin

Mick Knutson

Java, JavaEE, J2EE, WebLogic, WebSphere, JBoss, Tomcat, Oracle, Spring, Maven, Architecture, Design, Mentoring, Instructor and Agile Consulting. http://www.baselogic.com/blog/resume

View all posts

Java / JavaEE / Spring Boot Channel

BLiNC Supporters

BLiNC Adsense

Archives

Newsletter