1

How do I nest subclasses with Hibernate?

For example, I have the following class hierarchy:

PageElement
- PageParagraph
- PageImage
- PageVideo
- PageAudio
- PageQuestion
  - PageFillInTheBlankQuestion
  - PageOpenEndedQuestion
  - PageMultipleChoiceQuestion
  - ...

This is the ideal object structure. How can I successfully map this using Hibernate? I would say that the PageQuestion abstract class is VERY important. It contains a lot of reusable properties and logic. I also need to reference PageQuestion specifically while not referencing PageElement <- this would be bad. I'd also like to query against all PageQuestion objects.

0

2 Answers 2

1

In Hibernate 4.0 (maybe earlier), you can use nested elements if you are using the table-per-hierarchy model.

Example class structure:

Word (has property "text", string)
- Subject (adds property "plural", boolean)
  - Pronoun (adds property "masculine", boolean)
  - ProperNoun (adds property "person", boolean)
- Verb (adds property "past_tense", boolean)

Example Hibernate mapping XML:

<class name="test.Word" table="words">
    <id name="id"><generator class="native"/></id>
    <discriminator column="word_type" type="string"/>
    <property name="text"/>
    <subclass name="test.Subject">
        <property name="plural"/>
        <subclass name="test.ProperNoun">
            <property name="person"/>
        </subclass>
        <subclass name="test.Pronoun">
            <property name="masculine"/>
        </subclass>
    </subclass>
    <subclass name="test.Verb">
        <property name="past_tense"/>
    </subclass>
</class>

Then, after running the following code (I've left out the class code, it's very basic and honestly only the object types themselves are significant for this example):

    HibernateUtil.beginTransaction();
    HibernateUtil.getCurrentSession().persist(new Word("blue"));
    HibernateUtil.getCurrentSession().persist(new Subject("chairs", true));
    HibernateUtil.getCurrentSession().persist(new ProperNoun("James", true));
    HibernateUtil.getCurrentSession().persist(new Pronoun("he", false, true));
    HibernateUtil.getCurrentSession().persist(new Verb("sat", true));
    HibernateUtil.commitTransaction();

The database ends up containing this information:

id, word_type, text, plural, person, masculine, past_tense,
1, test.Word, blue, NULL, NULL, NULL, NULL
2, test.Subject, chairs, 1, NULL, NULL, NULL
3, test.ProperNoun, James, 0, 1, NULL, NULL
4, test.Pronoun, he, 0, NULL, 1, NULL
5, test.Verb, sat, NULL, NULL, NULL, 1

And querying the list of objects back results in the proper types:

    HibernateUtil.beginTransaction();
    List<Word> words = HibernateUtil.getCurrentSession().createCriteria(Word.class).list();
    for (Word w:words)
        System.out.println(w);
    HibernateUtil.commitTransaction();

Prints:

test.Word@caf6c1
test.Subject@10e35d5
test.ProperNoun@18e8541
test.Pronoun@1ce85c4
test.Verb@17aece8

See section 10.1.1 of http://docs.jboss.org/hibernate/core/4.0/manual/en-US/html/inheritance.html (it is essentially the same as the old docs though), although unfortunately it does not clearly indicate that nested subclasses are allowed -- but it is an easy thing to experiment with.

I agree that the Hibernate documentation is very poorly organized. Everything is there but I find that something about the way it is organized makes it very difficult for me to find complete information; mostly due to over use of cross-references, and a use-case oriented layout that doesn't always cover all the bases. However, the information is there.

Sign up to request clarification or add additional context in comments.

Comments

0

Thats exactly the issue between Object and Relational paradigm.

Hibernate is the tool for this. And there you have the reference do already for this.

http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#d0e6906

1 Comment

I figured out how to do it with a table-per-hierarchy pattern. It is odd that hibernate file looks nothing like the examples shown in that document. The document is not exhausted enough.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.