HIBERNATE JBoss.org
 |  Register  | 
     
News 
About 
   Feature List 
   Road Map 
Documentation 
   Related Projects 
   External Documentation 
Download 
Forum & Mailinglists 
Support & Training 
JIRA Issue Tracking
Wiki Community Area


Hibernate Public Training Courses


Get Hibernate in Action eBook!


JavaWorld 2003 Finalist


Jolt Award 2004 Winner
      
Documentation > Community Area > Middlegen for Hibernate

Middlegen for Hibernate

Middlegen - version 2.x http://boss.bekk.no/boss/middlegen/, with version 3.x moving to http://middlegen.codehaus.org/ open source tool.

What is Middlegen?

Middlegen is an open source code generation framework that provides a general-purpose database-driven engine using various tools such as JDBC, Velocity, Ant and XDoclet.

What is it good for?

The benefit of using Middlegen is that you can use an existing database design, optionally fine tune the settings, then Middlegen generates directly (or indirectly using additional tools and processes) all the repetitive, tedious to write code and configuration files for you.

What is the relationship to Hibernate?

The Middlegen design includes a plug-in architecture which facilitates particular aspects of a target system. Existing plugins include, simple java classes, EJB, JDO and now (close to) complete support for Hibernate. The hibernate plugin focuses on the generation of the mapping configuration files. Hibernates' excellent native hbm2java tool can be used to generated the domain classes.

Where can I find it?

The plugin has been initially created for the version 2.x series of Middlegen found at this project website. Feel free to ask questions on the mailing list (middlegen-user@lists.sourceforge.net) or under the Hibernate tools forum. The effort on version 3.x series of Middlegen is currently the primary focus of the core Middlegen development team and as such the Hibernate plugin will definately be ported to the new platform. The plugin status, some source and patches are to be found in the Middlegen JIRA bug tracking system [until the next beta is release (expected to be V3.0b1)]. Middlegen 2.x source in located on Sourceforge in CVS head (from the vo [final]) release (plugin release 4).

While Middlegen 3.x is being created, I have released a preview package(s) on the Hibernate sourceforge files site to allow all users to get started using the plugin with minimal effort. The package also demonstrates one possible way to setup a development environment. Once Middlegen 3.x beta is released then the v2.x package(s) will become redundant.

How do I use Middlegen?

Middlegen provides an Ant task from which to initiate the code generation for the target platforms. The task can include more than a single target, eg, Hibernate and EJB target. The following task is configured for the Hibernate plugin only.

<!-- ============================================================== -->
<!-- Run Middlegen -->
<!-- ============================================================== -->

<target
   name="middlegen"
   description="Run Middlegen"
   unless="middlegen.skip"
   depends="init,fail-if-no-xdoclet-1.2,check-driver-present,panic-if-driver-not-present"
>
  <mkdir dir="${build.gen-src.dir}"/>
  <echo message="Class path = ${basedir}"/>

  <taskdef
    name="middlegen"
    classname="middlegen.MiddlegenTask"
    classpathref="lib.class.path"
  />

  <middlegen
    appname="${name}"
    prefsdir="${src.dir}"
    gui="${gui}"
    databaseurl="${database.url}"
    initialContextFactory="${java.naming.factory.initial}"
    providerURL="${java.naming.provider.url}"
    datasourceJNDIName="${datasource.jndi.name}"
    driver="${database.driver}"
    username="${database.userid}"
    password="${database.password}"
    schema="${database.schema}"
    catalog="${database.catalog}"
  >

     <!-- Plugins -->
     <hibernate
        destination="${build.gen-src.dir}"
        package="${name}.hibernate"
        javaTypeMapper="middlegen.plugins.hibernate.HibernateJavaTypeMapper"
     />

   </middlegen>
   <mkdir dir="${build.classes.dir}"/>
</target>

The majority of the task options involves setting up the data source. Fine-tuning of the generation process is provide primarily through a Java Swing based GUI. This is activated when the gui option in the Middlegen Ant task is true. Middlegen has a sample application that can provide a guide for your own project adoption of Middlegen.

What is generated by the Hibernate plugin?

The Hibernate plugin generates the XML mapping document for Hibernate 2 only (This can be easily changed with additional templates). The motivation for this that a single output stream is easier to be maintained. Following is an example of the a mapping file generated by the plugin.

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >

<hibernate-mapping>
<!--

Created by Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/

-->
<class
  name="airline.hibernate.Flight"
  table="flights"
  schema="fdgdf"
  proxy="airline.hibernate.Flight"
>
  <meta attribute="implements">net.sf.hibernate.Lifecycle</meta>
  <meta attribute="scope-class">protected</meta>
  <id
    name="flightId"
    type="java.lang.Long"
    column="flight_id"
  >
    <generator class="assigned" />
  </id>
  <timestamp
     name="departureUtc"
     column="departure_utc"
  />
  <property
     name="name"
     type="java.lang.String"
     column="name"
     insert="false"
     not-null="true"
     length="32"
  />
  <property
     name="arrivalUtc"
     type="java.sql.Timestamp"
     column="arrival_utc"
     not-null="true"
  >
  <meta attribute="field-description">
     This is a field description for the property
  </meta>
  <meta attribute="scope-get">protected</meta>
  </property>

  <!-- associations -->
  <!-- bi-directional one-to-many association to Reservation -->
  <set
     name="reservations"
     lazy="true"
     inverse="true"
  >
     <key>
       <column name="flight_id_fk" />
     </key>
     <one-to-many
       class="airline.hibernate.Reservation"
     />
  </set>
</class>
</hibernate-mapping>

From release 3 of the plugin XDoclet markup can be generated using meta tags in the hbm mapping document. In addition, compound keys can be generated as internal rather than the default (and recommended) external class. These options are set using the Ant script. For example XDoclet generation:

 <hibernate
      destination="${build.gen-src.dir}"
      package="${name}.hibernate"
      genXDocletTags="true"
 />

The internal generation of composite keys can be selected as below.

 <hibernate
      destination="${build.gen-src.dir}"
      package="${name}.hibernate"
      genIntergratedCompositeKeys="true"
 />

They can be combined. The default is false for both options thus you are not required to included these options if false is appropriate. NOTE: Post hibernate 2.1beta6 DTD is required to validate correctly for all possible XDoclet meta tags.

From release 4 of the plugin custom Java type mapper can be created and hence applied during the initial type allocation phase and the resulting selection used during the generation phase(s). Any mapping that has been previously selected or fine tuned through the use of the GUI will not be modified by the mapper. Release 4 includes an improved JavaMapper and it is recommended this is used rather than the Middlegen core default selection. For example to install the standard custom java mapper:

 <hibernate
      destination="${build.gen-src.dir}"
      package="${name}.hibernate"
      javaTypeMapper="middlegen.plugins.hibernate.HibernateJavaTypeMapper"
 />

To create your own custom Java type mapper you just need to extend the middlegen.plugins.hibernate.interfaces.JavaTypeMapper interface

public interface JavaTypeMapper {
   /**
    * Gets the PreferredJavaType attribute of the JavaTypeMapper object
    */
   public String getPreferredJavaType(JavaColumn column);
}

and reference the class in the Ant script under the hibernate plugin tag.

Refer to the HibernateJavaTypeMapper and the documentation as an example.

The excellent native Hibernate hbm2java tool can be used (optionally through Ant) to generated the Java domain objects. In fact, the Hibernate plugin employs the meta tags to provide domain code generation preferences designed for hbm2java processing. Here is the Ant task required to generate the POJOs using hbm2java.

<target name="hbm2java"
    description="Generate .java from .hbm files.">

    <hbm2java config="${build.dir}/hibernate.cfg.xml"
       output="${gensrc.dir}"
    >
       <fileset dir="${gensrc.dir}">
            <include name="**/*.hbm.xml"/>
       </fileset>
   </hbm2java>
</target>

Currently setting the cascading options on the relationships is no possible (will be in the near future) so you can post process the hbm files to select the appropriate setting. The following Ant target illustrates one approach using the replaceregex Ant task.

<target name="hbm2java"
   description="Generate .java from .hbm files." depends="init">
   <property name="hbm.dir" location="${build.generate.dir}/com/mappings/"/>
           
   <replaceregexp
    match='cascade="none"'   
    replace='cascade="all"'
    byline="true">
    <fileset dir="${hbm.dir}" includes="MapRequest.hbm.xml,MapRun.hbm.xml" /> 
   </replaceregexp>
      
   <mkdir dir="${build.generate.dir}"/>
   <taskdef
      name="hbm2java"
      classname="net.sf.hibernate.tool.hbm2java.Hbm2JavaTask"
      classpathref="hibernate.classpath"
   />
      
   <hbm2java output="${build.generate.dir}" classpathref="hibernate.classpath">
      <fileset dir="${build.generate.dir}">
         <include name="**/*.hbm.xml"/>
      </fileset>
   </hbm2java>
</target> 

The process can be managed using as in a single step by adding a dependency on the hbm2java target on the Middlegen target. This will automatically generate the code as soon as you have finished with Middlegen.

Feature set of the Hibernate Plugin

The plugin is designed to be the best Middlegen plugin :-) and provide a feature full solution for those that like to (or must) work using a bottom up strategy. The plugin provides:

  • The bulk of the options for both direct Hibernate mapping attributes and hbm2java meta attributes.
  • Appropriate GUI enhancements (See images in Middlegen JIRA). This allows easily selecting the various options and using the faciltiies provided.
  • Storing the GUI state for both the Table and Columns so that it is correctly restored each fine tuning or code generation session.
  • Full support for setting attributes across multiply selected columns (I don't allow multiple select for some properties, eg, the gen-property meta attribute).
  • Added silent unique mapping attribute (not a part of the GUI).
  • Full Relationship support (through foreign keys), eg, one-to-one, one-to-many, many-to-one, many-to-many with either uni- and bi-directional associations. Note: One-to-one with foreign keys requires hibenate 2.1.
  • Compound key support. Method uses an external Java class to hold the key fields.
  • No primary key tables are generated a single compound key property.
  • XDoclet markup for POJO generation to allow prototyping for top-to-bottom development.
  • Generate the hbm file appropriately (decided to not generate any optional XML attributes if it is not required and setting is equal to the default or an empty value).
  • Custom Java type mapper plugin provider facility (start of Plugins for this Plugin).

The areas I have not implemented (as yet) include: polymorphism (and associate items), generated class name meta attribute, meta finder method and meta session method, or inheritance of meta data options (This is likely to be asked for in the future (assuming it gets a user base) but at this stage it will overload the GUI and I did not want to get to complicated).

What about Hibernates' ddl2hbm tool?

The ddl2hbm tool formally known as the Reverse Engineering Tool targets the same functionality as the Hibernate Middlegen plugin. Non-core systems are being moved into external jar packages. This includes ddl2hbm which is being moved to the HibernateExt/tools CVS repository and tools jar. Hibernates' core goal is to do one thing very well, thus over time, it is likely that the Middlegen plugin will be the primary tool for generating hibernate mapping's directly from JDBC data sources.

--David

      

coWiki