Generating DDL Scripts from JPA Annotations with Maven

A while ago I posted an article that showed how to generate a database schema from JPA annotations. Since I didn’t get the hibernate3 maven plugin working back then I used the antrun plugin as a workaround. Thanks to the help of a reader the plugin works now, so an update is in order.

Since the last article the scenario hasn’t changed: I want to generate DDL scripts for creating a database schema from JPA annotations. The created schema can then be tweaked as necessary and used in the production environment. Like the old antrun solution, the maven plugin uses the ant task from Hibernate Tools, so the resulting schema is the same.

This is how it works. Edit your pom.xml and add the plugin configuration:

<build>
  <plugins>
    <!-- other plugins ... -->
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>hibernate3-maven-plugin</artifactId>
      <version>2.2</version>
      <executions>
        <execution>
          <phase>process-classes</phase>
          <goals>
            <goal>hbm2ddl</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <components>
          <component>
            <name>hbm2ddl</name>
            <implementation>jpaconfiguration</implementation>
          </component>
        </components>
        <componentProperties>
          <persistenceunit>Default</persistenceunit>
          <outputfilename>schema.ddl</outputfilename>
          <drop>false</drop>
          <create>true</create>
          <export>false</export>
          <format>true</format>
        </componentProperties>
      </configuration>
    </plugin>
  </plugins>
</build>

Make sure that the persistence unit’s name in pom.xml (“Default” in this example) is consistent with the name assigned in persistence.xml. Additionally, you have to set the hibernate.dialect property or Hibernate won’t be able to generate a DDL script that’s compatible with your type of database.

Schema creation is executed in the process-classes phase, so you’ll find the schema in target/hibernate3/sql/schema.ddl after running mvn package (or any later phase). An alternative is to remove the <executions> element and to run the hbm2ddl goal from the command line:

  mvn hibernate3:hbm2ddl

The plugin offers a lot more than just schema creation. See the plugin documentation for more information.

About these ads
This entry was posted in java and tagged , , . Bookmark the permalink.

24 Responses to Generating DDL Scripts from JPA Annotations with Maven

  1. kumar says:

    hi,
    what do you mean by “Don’t forget to set the persistence unit to whatever you declared in persistence.xml”

    To use this do I need to add mappings to all my annotated classes in hibernate.cfg.xml??
    thx

  2. mafr says:

    In your persistence.xml you’ll find an element “persistence-unit” with an attribute “name”. The value of this attribute has to match “persistenceunit” in your maven configuration. You can set them both to “Default”, for example.

    You don’t have to add mappings to hibernate.cfg.xml. The maven plugin finds them automatically.

    Cheers,
    Matthias

  3. Bruce says:

    Hi,
    I’m getting the following error. I don’t have a hibernate config but other than trying to generate the ddl everything works fine. Do I need this file just so that the ddl can be generated?

    Thanks

    Bruce
    [INFO] src/main/resources/hibernate.cfg.xml not found within the project. Trying absolute path.
    [INFO] No hibernate configuration file loaded.
    [INFO] src/main/resources/database.properties not found within the project. Trying absolute path.
    [INFO] No hibernate properties file loaded.
    [INFO] ————————————————————————
    [ERROR] FATAL ERROR
    [INFO] ————————————————————————
    [INFO] The dialect was not set. Set the property hibernate.dialect.
    [INFO] ————————————————————————

  4. mafr says:

    The plugin doesn’t know for which flavor of database it should generate the DDL script. You have to supply the “hibernate.dialect” property somehow, either using a hibernate.cfg.xml file or via persistence.xml where you can also set properties for a persistence unit.

  5. Kwan says:

    When using hibernate config (not jpaConfiguration), these following lines applied (position hibernate.cfg.xml at absolute pasth):-

    hbm2ddl

    annotationconfiguration

    annotationconfiguration

    hibernate.cfg.xml

    /Kwan

  6. Chandan Benjaram says:

    Hi-

    I am trying your approach to generate db(MySQL) schema out of JPA Annotations in Maven way. I am getting following error during project build:
    ‘[ERROR] Persistence unit not found: ‘someunit’.
    Build errors for server; org.apache.maven.lifecycle.LifecycleExecutionException: Internal error in the plugin manager executing goal ‘org.codehaus.mojo:hibernate3-maven-plugin:2.0-alpha-2:hbm2ddl’: Mojo execution failed.’

    I have my persistence unit in META-INF/persistence.xml and this is the only one XML in my whole project.

    For your information, here is my POM.xml hibernate3-maven configuration snippet:

    org.codehaus.mojo
    hibernate3-maven-plugin
    2.0-alpha-2

    hbm2ddl
    annotationconfiguration

    true
    true
    true
    jpaconfiguration
    someunit
    schema.sql
    schema.sql

    target/test-classes
    target/test-classes

    ${maven.test.skip}

    process-test-resources

    hbm2ddl

    I tried in Ant way, still no GO :-(
    I verified perstence.xml and its is getting into classpath of application.
    Do you have any idea about whats wrong with this?

    -Chandan Benjaram

    • Shrirang says:

      Persistence.xml need not be directly in classpath. It expects it to be in folder META-INF

    • Tom M. says:

      Did you get this resolved ?

      ‘[ERROR] Persistence unit not found:

      I’m have the same issue.

      • hdave says:

        I have the same issue too…whats the resolution?

      • Pm says:

        In your persistence.xml you must have the following line:

        In the pom.xml set the persistentunit like this : jpaPU

        jpaPU is the name I defined in my persistence.xml

  7. Lks says:

    Hi, Marf! This is my error:
    ————————–
    [0] Inside the definition for plugin ‘hibernate3-maven-plugin’ specify the following:


    VALUE

    -OR-
    on the command line, specify: ‘-Dhibernatetool=VALUE’
    ————————–
    I think this is because I set the persistent unit parameters via Spring. Do you know if there is a solution using Spring-Jpa-Hibernate? regards

    • Lks says:

      I’ve solved setting the correct value for persistentUnit.
      Besides, I’ve added the following tag, inside :
      ${basedir}/src/main/resources/database.properties
      database.properties, contains the dialect of my database engine:
      hibernate.dialect=org.hibernate.dialect.MySQLDialect

  8. Pingback: So Much for 2010 « Unmaintainable

  9. Mandar says:

    Request you to update it to the latest Hibernate version.Currently it uses an older version of hibernate-core(and other supporting) API.

  10. Mandar says:

    Here is a Dependency configuration to work with Hibernate 3.6.1 + JPA 2.0 :

    org.hibernate.javax.persistence
    hibernate-jpa-2.0-api
    1.0.0.Final

    org.hibernate
    hibernate-commons-annotations
    3.2.0.Final

    javax.validation
    validation-api
    1.0.0.GA

    org.hibernate
    hibernate-validator
    4.1.0.Final

    org.hibernate
    hibernate-commons-annotations
    3.2.0.Final

    org.hibernate
    hibernate-tools
    3.2.4.GA

    org.hibernate
    hibernate-core
    3.6.1.Final

    org.jboss.slf4j
    slf4j-jboss-logging
    1.0.2.GA

    org.jboss.logging
    jboss-logging
    3.0.0.Beta4

  11. Pavel says:

    Hi!
    I’m using hibernate together with Spring and I do not have hibernate.cfg.xml

    I receive an error “No hibernate configuration file loaded.”

    How can I solve it?

    Thank you

    • Samuel says:

      Hi Pavel,

      in your case, you probably need to put a database.properties file in src/main/resources folder, containing hibernate properties (Dialect, at least)

      So, mine is :
      hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

      Hope this helps,
      Samuel

  12. tirtavium says:

    Hi! why always error like that, do you know why ?
    [ERROR] FATAL ERROR
    [INFO] ————————————————————————
    [INFO] The plugin descriptor for the plugin Plugin [org.codehaus.mojo:hibernate3-maven-plugin] was not found. Please verify that the plugin JAR /home/tirtavium/.m2/repository/org/codehaus/mojo/hibernate3-maven-plugin/2.2/hibernate3-maven-plugin-2.2.jar is intact.
    [INFO] ————————————————————————
    [INFO] Trace
    java.lang.IllegalStateException: The plugin descriptor for the plugin Plugin [org.codehaus.mojo:hibernate3-maven-plugin] was not found. Please verify that the plugin JAR /home/tirtavium/.m2/repository/org/codehaus/mojo/hibernate3-maven-plugin/2.2/hibernate3-maven-plugin-2.2.jar is intact.
    at org.apache.maven.plugin.DefaultPluginManager.addPlugin(DefaultPluginManager.java:360)
    at org.apache.maven.plugin.DefaultPluginManager.verifyVersionedPlugin(DefaultPluginManager.java:224)
    at org.apache.maven.plugin.DefaultPluginManager.verifyPlugin(DefaultPluginManager.java:184)
    at org.apache.maven.plugin.DefaultPluginManager.loadPluginDescriptor(DefaultPluginManager.java:1642)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.verifyPlugin(DefaultLifecycleExecutor.java:1540)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.getMojoDescriptor(DefaultLifecycleExecutor.java:1787)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.segmentTaskListByAggregationNeeds(DefaultLifecycleExecutor.java:462)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:175)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
    at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    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)

  13. Campa says:

    Thank you very much !!

  14. Great idea, and it used to work. Then it stopped working. It either hangs forever, or says that the ‘process-classes’ phase does not exist

  15. Pablo says:

    GROSSO DE LA VIDA.

    Estuve buscando esto por mil lados distintos, y no lo pude encontrar, hasta que te leí…

    Muchas gracias!!!

    (If you don’t speak spanish: “Thanks for all that fish!”)

  16. OmahaBen says:

    I have commented out the section and running the command mvn hibernate3:hbm2ddl. I am getting these comment’s repeatedly and cannot go any further beyond this point.

    DEBUG org.hibernate.util.DTDEntityResolver – trying to resolve system-id [http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd]

    Please help!

    • Lks says:

      If you are running maven behind a proxy, try to add the proxy settings, in the $MAVEN_HOME/conf/settings.xml file.

Comments are closed.