Search code examples
javahibernategradleanthibernate-tools

Hibernate Tools reverse engineering with Gradle


When I was using Eclipse as my IDE, I used to use Hibernate Tools to reverse engineer a database to obtain my entities, complete with annotations.

I recently moved to IntelliJ IDEA, which I consider to be an overral better IDE, but unfortunately there isn't a port of Hibernate Tools for it, so I cannot generate my entities the way I used to. I know that IntelliJ IDEA has its own reverse engineer tool (the one accessible via Persistence->Generate Persistence Mapping->By Database Schema), but I found it to be somewhat buggy, sometimes generating entities which are plain wrong.

I know that Hibernate Tools can be also used from Ant. Is there a way to use it from Gradle, too?


Solution

  • I managed to use Hibernate Tools from Gradle, largely thanks to this question.

    It turns out (I didn't know it) that Gradle is indeed capable of calling Ant tasks, so it is possible to use the preexisting Hibernate Tools Ant task to reverse engineer a database.

    To do so, it is necessary to have a hibernate.cfg.xml file, which contains the configuration needed to tell the Ant ask how to access our database. This is an example:

    <?xml version = "1.0" encoding = "utf-8"?>
    <!DOCTYPE hibernate-configuration SYSTEM
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
            <property name="hibernate.dialect">
                org.hibernate.dialect.MySQLDialect
            </property>
            <property name="hibernate.connection.driver_class">
                com.mysql.jdbc.Driver
            </property>
            <property name="hibernate.connection.url">
                jdbc:mysql://localhost:3306/mydb
            </property>
            <property name="hibernate.connection.username">
                username
            </property>
            <property name="hibernate.connection.password">
                password
            </property>
        </session-factory>
    </hibernate-configuration>
    

    (IntelliJ may complain about this file, telling that it cannot find the driver, but this is ok, as they will be provided by Gradle during the execution)

    This config file will be used by the Ant task called from Gradle. I put it in a new db folder, created in the project root.

    The following needs to be added to the build.gradle file:

    configurations {
        reverseMap
    }
    
    dependencies {
        //...your other dependencies...
        reverseMap 'org.hibernate:hibernate-core:4.0.1.Final'
        reverseMap 'org.hibernate:hibernate-tools:4.0.1.Final'
        reverseMap 'org.slf4j:slf4j-simple:1.7.5'
        reverseMap 'mysql:mysql-connector-java:5.1.48'
    }
    
    project.ext {
        hibernateDestDir = file("$projectDir/src/main/java")
    }
    
    task reverseMap {
        outputs.dir hibernateDestDir
        doLast {
            hibernateDestDir.exists() || hibernateDestDir.mkdirs()
            ant {
                taskdef(
                    name: 'hibernatetool',
                    classname: 'org.hibernate.tool.ant.HibernateToolTask',
                    classpath: configurations.reverseMap.asPath
                )
                hibernatetool(destdir: hibernateDestDir) {
                    jdbcconfiguration(
                        configurationfile: "$projectDir/db/hibernate.cfg.xml",
                        packagename: "com.me.models"
                    )
                    hbm2java(
                        jdk5: true,
                        ejb3: true
                    )
                }
            }
        }
    }
    
    

    This code creates a new configuration called reverseMap, which can be used to declare the dependencies needed for the reverseMap task (hibernate-core,hibernate-tools and log4j are needed, while the driver should be the one needed for your DBMS).

    The reverseMap code calls the Ant task, basically following the official guide. The part of interest is hbm2java, which is the actual exporter. The rest of the code is basically glue code for the Ant task and configuration.

    The Gradle task can be called either from the command line (./gradlew reverseMap) or from IntelliJ.