Tarin Gamberini

A software engineer and a passionate java programmer

How to generate DDL with Hibernate 4, Hibernate Tools and Maven

Hibernate Tools is a toolset for Hibernate3 implemented as an integrated suite of Eclipse plugins, together with a unified Ant task for integration into the build cycle.

Working with Maven you can use the hibernate3-maven-plugin. But this is (as the name states) only for Hibernate 3 and does not support Hibernate 4.

As reported by Thomas Letsch [1] the Hibernate tools for Hibernate 4.x is not yet finished, and the obvious solution is to just use the Maven ant-run plugin and execute the hibernate-tools Ant task. So following the Thomas Letsch’s article I have worked out a solution that suits me well.

Table of Contents

Integrating hibernatetool Ant Task and Maven

Because I want to use the <hibernatetool> Ant Task [2] through Maven the first thing I have done was configuring the maven-antrun-plugin [3]:

pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<build>
    <plugins>
        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.7</version>
            <executions>
                <execution>
                    <phase>test-compile</phase>
                    <configuration>
                        ...
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

I have bound the run goal to the test-compile phase so <hibernatetool> will generate everything before running tests.

Into the <configuration> tag’s body I have written my target which starts, and finish, with debug messages:

pom.xml
1
2
3
4
5
<target>
    <echo message="Ant target, through maven-antrun-plugin, started" />
    ...
    <echo message="Ant target, through maven-antrun-plugin, terminated" />
</target>

As described in “Using tasks not included in Ant’s default jar” [3] I should have used maven.plugin.classpath into the:

pom.xml
1
2
3
<taskdef name="hibernatetool"
    classname="org.hibernate.tool.ant.HibernateToolTask"
    classpathref="maven.plugin.classpath" />

and than I should have written hibernate-tools artifact, and all of its dependencies, into the plugin’s <dependencies>:

pom.xml
1
2
3
4
5
6
7
8
9
10
11
<plugin>
    ...
    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-tools</artifactId>
            <version>4.0.0-CR1</version>
        </dependency>
        ...
    </dependencies>
</plugin>

but because there are too many dependencies to write, as shown at hibernate-tools depends on, I have preferred to leverage on Maven dependency management declaring the hibernate-tools artifact as one of my project dependency, leaving Maven finding out the transitive dependencies:

pom.xml
1
2
3
4
5
6
7
8
9
10
<project>
    ...
    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-tools</artifactId>
            <version>4.0.0-CR1</version>
            <scope>test</scope>
        </dependency>
        ...

Moreover because dependencies on maven.plugin.classpath are not packaged in the jar I have explicity excluded hibernate-tools, and its dependencies, from my project packaging declaring them in the test scope. Thus hibernate-tools dependencies were both on the maven.plugin.classpath and the maven.test.classpath, so I have defined hibernatetool.path [4] that groups the compile and the test classpath.

pom.xml
1
2
3
4
5
6
<property name="maven_compile_classpath" refid="maven.compile.classpath" />
<property name="maven_test_classpath" refid="maven.test.classpath" />
<path id="hibernatetool.path">
    <pathelement path="${maven_compile_classpath}" />
    <pathelement path="${maven_test_classpath}" />
</path>

Despite what states the documentation about referencing the Maven classpaths [3] writing <pathelement path="maven.test.classpath" /> does not work for my project. So I have set ant properties that refer to appropriate Maven classpaths.

In the end the hibernatetool task definition looks like:

pom.xml
1
2
3
<taskdef name="hibernatetool"
    classname="org.hibernate.tool.ant.HibernateToolTask"
    classpathref="hibernatetool.path" />

Finally I have configured the hibernatetool to export a ddl file in the ${project.build.directory}/classes directory:

pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
<hibernatetool destdir="${generatedByHibernate.outputDirectory}">
    <classpath>
        <path location="${project.build.directory}/classes" />
    </classpath>
    <configuration configurationfile="${project.build.directory}/classes/hibernate.cfg.xml" />
    <hbm2ddl
        export="true"
        drop="true"
        create="true"
        outputfilename="helloworld.ddl"
        format="true" />
</hibernatetool>

Of course just before the hibernatetool tag I have defined and created such directory:

pom.xml
1
2
3
4
5
<property
    name="generatedByHibernate.outputDirectory"
    value="${project.build.directory}/generated/hibernatetool" />
<mkdir
    dir="${generatedByHibernate.outputDirectory}" />

You can download the full pom from my GitHub account.

Generate DDL

To generate DDL, or see pom.xml with different hibernatetool configurations, you may look at one of the following Maven project:

and run mvn clean test.

Bibliography

[1]
Generate DDL with Hibernate Tools, JPA and Maven: an excellent work by Thomas Letsch about integrating <hibernatetool> Ant Task and Maven
[2]
Hibernate Tools Reference Guide: in particular the chapter about “Ant Tools”.
[3]
The Maven AntRun Plugin: in particular the examples Referencing the Maven Classpaths and Using tasks not included in Ant’s default jar
[4]
Path-like structures

Post a comment

A comment is submitted by an ordinary e-mail. Your e-mail address will not be published or broadcast.

This blog is moderated, therefore some comments might not be published. Comments are usually approved by the moderator in one/three days.