Big Al\’s Blog

Software Engineering, Enterprise Computing and The Digital Divide

Self-referencing classes in Hibernate

Posted by Big Al on August 4, 2006

I’m relatively new to Hibernate and love the functionality it provides, not to say the amount of time it saves me from writing entity classes, jdbc code, and SQL tables. However, I found it strange that the Hibernate manually did not any examples of setting up self-referencing classes that you would normally have in a parent/child structure. The example they have for parent/child structures are with classes of two different types, what I am talking about here is a class that has children of the same type as it self. For example if you have a hierachy of categories:

Class on the left is how it would look in the analysis model, the class on the right is how it would look when implemented

As an E/R diagram this would be realised as:

One category can have many sub categories. One sub category can have only one parent category

 

This structure could be formulated as the following Hibernate mapping:

 

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="mypackage">

<class name="Category" table="CATEGORY">

<id name="id" type="int">
            <meta attribute="use-in-equals">true</meta>
            <column name="CATEGORY_ID" />
            <generator class="native" />
        </id>

<property name="categoryName" type="string">
            <meta attribute="use-in-tostring">true</meta>
            <column name="CATEGORY_NAME" length="150" not-null="true" unique="false" index="CATEGORY_NAME" />
        </property>

<bag name="subCategories" lazy="false" cascade="all-delete-orphan" inverse="true">
            <key column="PARENT_CATEGORY_ID" />
            <one-to-many class="Category" />
        </bag>

<many-to-one name="parentCategory" class="Category">
            <column name="PARENT_CATEGORY_ID" />
        </many-to-one>
    </class>

</hibernate-mapping>

If you run the above mapping through the hbm2java task in Ant (or Eclipse with JBOSS-IDE installed) you should get a class as described on the class diagram above. If you also run the mapping through hbm2ddl (to MySQL) you should get the SQL script below

CREATE TABLE `category` (
    `CATEGORY_ID` int(11) NOT NULL auto_increment,
    `CATEGORY_NAME` varchar(150) NOT NULL,
    `PARENT_CATEGORY_ID` int(11) default NULL,
    PRIMARY KEY  (`CATEGORY_ID`),
    KEY `CATEGORY_NAME` (`CATEGORY_NAME`),
    KEY `FK31A8ACFEAF2C96DF` (`PARENT_CATEGORY_ID`),
    CONSTRAINT `FK31A8ACFEAF2C96DF` FOREIGN KEY (`PARENT_CATEGORY_ID`) REFERENCES `category` (`CATEGORY_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

There are other ways of mapping the one-to-many relationship, but I’m leading to this solution as I need the relationship to be inverse so that I can get a parent from a child, and from a parent to all its children.

Comments on this approach are welcome

7 Responses to “Self-referencing classes in Hibernate”

  1. Venkat Sadasivam said

    Look into the following link.
    http://www.hibernate.org/86.html

  2. John said

    There is an example in the Hibernate documentation
    http://www.hibernate.org/hib_docs/reference/en/html/collections.html

    Particularly, see section 6.11. Collection examples

  3. Mark said

    I’ve been looking everywhere for something like this. It was very well documented and simple. You should work for Hibernate/Jboss šŸ˜‰

  4. swamy said

    Can I get an equivalent annotation class for this?

  5. Gloomy said

    — Can I get an equivalent annotation class for this?

    Here you are šŸ™‚

    @Entity
    @Table(name=”employee”)
    public class Employee {

    private long id;

    private Employee chief;

    @Id
    @GeneratedValue
    @Column(name = “id”)
    public long getId() {
    return id;
    }

    @ManyToOne
    @JoinColumn
    public Employee getChief() {
    return chief;
    }
    }

  6. Ray said

    Hi, anyone know how to pull this of with a many-to-many relationship? It needs a second table, but I’m new to hibernate, and haven’t a clue how to map it. any help or pointers would be most appreciated.

  7. Cool site, love the info.

Sorry, the comment form is closed at this time.