Generating DDL Scripts with Maven
Java’s persistence API (JPA) makes object-relational mapping very convenient. Using Hibernate, tables and sequences are generated automatically which speeds up development significantly. However, in production systems automatic schema creation isn’t desired. In many cases you would want to tune the schema a bit, like adding an index for speeding up common access paths, renaming constraints and the like. Additionally, an application should run with as little DB privileges as possible, so it is possible that CREATE TABLE is simply not permitted.
[UPDATE: See this article for a pure maven solution.]
The usual approach is to create a DDL script containing the required CREATE commands and execute it on the database before deploying the application. Unfortunately, this is a large task if you have many entities and with foreign key constraints, the order of commands matters. So it would be nice if we could generate a working DDL script from our JPA annotations that can be adjusted manually.
Using Hibernate and the hibernatetool Ant task, this is possible. In the following example, I’ll show how to configure a Maven project which used the antrun plugin to execute hibernatetool from within Maven.
First of all, we have to attach the antrun plugin to Maven’s lifecycle. Add the following to your pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>process-classes</id>
<phase>process-classes</phase>
<configuration>
<tasks>
<ant antfile="src/main/ant/build.xml" inheritRefs="true">
<target name="schemaexport"/>
</ant>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-tools</artifactId>
<version>3.2.0.beta9a</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.2.1.ga</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
The plugin configuration references an external build.xml file which contains the hibernatetool invocations. Create a directory src/main/ant and add the following build.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<!--
Generate DDL files for schema creation.
-->
<target name="schemaexport">
<taskdef name="hibernatetool"
classname="org.hibernate.tool.ant.HibernateToolTask"/>
<hibernatetool destdir="target">
<classpath refid="maven.compile.classpath"/>
<!-- Use JPA annotations, as opposed to Hibernate's hbm
files. If there are multiple persistence units, specify
the correct one using the "persistenceunit" attribute.
-->
<jpaconfiguration />
<!-- Write all CREATE statements to a file. -->
<hbm2ddl drop="false" create="true" export="false"
outputfilename="schema-create.ddl"
delimiter=";" format="true"/>
<!-- Write all DROP statements to a different file. -->
<hbm2ddl drop="true" create="false" export="false"
outputfilename="schema-drop.ddl"
delimiter=";" format="true"/>
</hibernatetool>
</target>
</project>
Now you can run mvn generate-classes and you will find two DDL files in the target directory: One for creating and one for dropping all tables.
Tags: build systems, java, maven
You can comment below, or link to this permanent URL from your own site.
September 25, 2007 at 05:58
Good article.
One question.
Can hibernate3:hbm2ddl from hibernate3-maven-plugin does the same as ant for you here? Ant invocation is considered to slow down maven execution time.
September 25, 2007 at 06:29
Unfortunately, I never got that plugin working, so I chose ant. If you know a way I’d appreciate to hear how you did it. Thanks!
December 12, 2007 at 09:11
This works for me:
http://lystochok.org.ua/2007/12/11/how-to-generate-ddl-schema-with-maven2/
OMax
December 13, 2007 at 22:07
Thanks a lot! I’ll try it as soon as my holidays are over and I’m back at work.
Cheers,
Matthias
April 12, 2008 at 00:52
Did you get it to work with maven2 only? Because lystochok’s post doesn’t seem to exist anymore. Thank you!
April 12, 2008 at 11:03
Yes, I finally got it working. Please see my latest article for the solution.