Как правильно отобразить вложенные подклассы, используя Hibernate - PullRequest
1 голос
/ 11 декабря 2011

Как вложить подклассы в Hibernate?

Например, у меня есть следующая иерархия классов:

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

Это идеальная структура объекта. Как я могу успешно отобразить это с помощью Hibernate? Я бы сказал, что абстрактный класс PageQuestion ОЧЕНЬ важен. Он содержит много повторно используемых свойств и логику. Мне также нужно ссылаться на PageQuestion специально, не ссылаясь на PageElement <- это было бы плохо. Я также хотел бы сделать запрос ко всем <code>PageQuestion объектам.

Ответы [ 2 ]

1 голос
/ 03 июля 2013

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

База данных содержит следующую информацию:

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

См. Раздел 10.1.1 http://docs.jboss.org/hibernate/core/4.0/manual/en-US/html/inheritance.html (хотя, по сути, он такой же, как и в старых документах), хотя, к сожалению, он не ясно указывает на то, что вложенные подклассы разрешены, но экспериментировать легко с.

Я согласен, что документация по Hibernate очень плохо организована. Все есть, но я нахожу, что что-то в том, как оно организовано, очень затрудняет мне поиск полной информации; в основном из-за чрезмерного использования перекрестных ссылок и ориентированного на прецедент макета, который не всегда охватывает все основы. Однако информация там .

0 голосов
/ 11 декабря 2011

Именно в этом и заключается проблема между объектной и реляционной парадигмой.

Инструмент Hibernate для этого.И там у вас есть ссылка сделать уже для этого.

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

...