如何使用 hibernate 正确映射嵌套子类

发布于 2024-12-20 09:50:52 字数 457 浏览 2 评论 0原文

如何使用 Hibernate 嵌套子类?

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

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

这是理想的对象结构。如何使用 Hibernate 成功映射它?我想说 PageQuestion 抽象类非常重要。它包含许多可重用的属性和逻辑。我还需要专门引用 PageQuestion,而不引用 PageElement <- 这会很糟糕。我还想查询所有 PageQuestion 对象。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

葵雨 2024-12-27 09:50:52

在 Hibernate 4.0(可能更早)中,如果您使用的是 table-per-hierarchy 模型,则可以使用嵌套元素。

类结构示例:

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

数据库最终包含此信息:

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

打印:

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

参见 http://docs.jboss.org/hibernate/core /4.0/manual/en-US/html/inheritance.html (本质上与旧文档相同),尽管不幸的是它没有明确表明允许嵌套子类 - 但它是一件很容易尝试的事情。

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

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.

夜吻♂芭芘 2024-12-27 09:50:52

这正是对象和关系范式之间的问题。

Hibernate 就是实现此目的的工具。那里已经有为此做的参考。

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文