Tuesday, April 12, 2011

Hibernate - Part 3 - Creating entity classes and database tables

My previous blog post described the basic process I used to configure my Eclipse Java project to use Hibernate.  At the time, I was playing around with the example code from the Harnessing Hibernate book.  I found the examples helpful and now I'm ready to start using Hibernate in my own Java project.

Hibernate gives you several options for creating your Java entity classes and database tables.  This is important and necessary because there will be times when we'll need to integrate Hibernate into existing projects where some combination of the entity classes and database tables may already exist.

In my case, I'm literally starting from scratch and need to create everything.  Should I use Hibernate mapping files (.hbm), Hibernate Annotations, or Java Persistence API (JPA) Annotations?

I played around with JPA Annotations as described in this tutorial video.  JPA has the advantage of being the Java standard and capable of working with ORM tools other than Hibernate.  I'd like to continue getting up to speed with JPA but for now I decided to use Hibernate mapping files (.hbm).

I copied an existing .hbm file from the samples included in Harnessing Hibernate and modified it for my own entity classes.  After all, isn't copying existing code how we always get started?  :)

At this point in my project, I have created an .hbm file for two entities: FlashCard and Tag.  What makes these interesting is that FlashCard contains a collection of Tag objects and will therefore need a join table (ie. flashcard_tag) in the database.  Here's where Hibernate shows its strength and ease of use.  We can define the relationship between these two entities in the mapping file and let Hibernate create the Java classes and database tables for us.  Hibernate understands the relationship.

Here's an excerpt from a mapping file where the relationship between FlashCard and Tag is defined:
        <set name="tags" table="FLASHCARD_TAGS">
            <meta attribute="field-description">Tags for this FlashCard</meta>
            <key column="FLASHCARD_ID" />
            <many-to-many class="org.robbins.flashcards.model.Tag"
                column="TAG_ID" />
        </set>
Now that I've got my Hibernate mapping files ready, I need to have Hibernate go ahead and create my Java entity classes and tables in the MySQL database.

I'm going to let Ant and the HibernateTool task generate the Java code and database tables.  Here's an excerpt from my build.xml which I adapted from the Harnessing Hibernate examples
    <!-- create the Java entity classes -->
    <target name="codegen" depends="prepare, refresh.local"
                description="Generate Java source from the O/R mapping files">
        <hibernatetool destdir="${source.dir}">
            <configuration configurationfile="${source.dir}/hibernate.cfg.xml" />
            <hbm2java jdk5="true" />
        </hibernatetool>
    </target>

    <!-- create the database tables -->
    <target name="schema" depends="prepare, refresh.local"
            description="Generate DB schema from the O/R mapping files">

        <delete dir="${data.dir}" />
        <mkdir dir="${data.dir}" />

        <hibernatetool destdir="${source.dir}">
            <configuration configurationfile="${source.dir}/hibernate.cfg.xml" />
            <hbm2ddl drop="yes" />
        </hibernatetool>
    </target>

1 comment:

  1. Hi I'm reading chapter 2 of Harnessing Hibernate, and I was wondering why I can't seem to get my hibernate.properties file to be picked up when generating the schema (using the schema task).

    When I run the schema task ant complains that I don't have my hibernate.dialect set, which is what makes me believe that it's not picking up my hibernate.properties.

    I've posted more details here:

    https://forum.hibernate.org/viewtopic.php?f=1&t=1013839&p=2451130#p2451130

    However I've noticed that in many of the questions I've looked through online most people seem to use the xml based configuration instead of hibernate.properties. I see that in chapter three they show you how to use this, and so I may end up just skipping to chapter 3 and configure the chapter 2 example using the xml file instead.

    ReplyDelete