2011-12-11 20 views
1

如何使用Hibernate嵌套子类?如何使用休眠正确映射嵌套子类

例如,我有下面的类层次结构:

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

这是理想的对象结构。我怎样才能成功地使用Hibernate映射这个?我会说PageQuestion抽象类是非常重要的。它包含很多可重用的属性和逻辑。我还需要特别参考PageQuestion,而不参考PageElement < - 这会很糟糕。我还想查询所有PageQuestion对象。

回答

1

在Hibernate 4.0(也许更早),你,如果你使用的是表每层次模型可以使用嵌套元素。

实例类结构:

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) 

实例Hibernate映射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> 

然后,运行下面的代码后(我已经离开了这个类的代码,这是很基本的,老老实实只对象类型本身对于该示例是重要的):

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(); 

该d atabase结束了包含此信息:

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 

和查询对象的列表回到正确类型的结果:

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

打印:

[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 

见节http://docs.jboss.org/hibernate/core/4.0/manual/en-US/html/inheritance.html 10.1.1 (尽管它与旧文档基本相同),但不幸的是,它没有清楚地表明嵌套子类是允许的 - 但这是一件容易的事情。

我同意Hibernate文档的组织很差。一切都在那里,但我发现有关组织方式的事情使我很难找到完整的信息;主要是由于过度使用交叉引用以及面向用例的布局,并不总是涵盖所有的基础。但是,那里的信息