Hibernate: Как смоделировать отношения двойного родителя / ребенка - PullRequest
1 голос
/ 09 мая 2011

У меня довольно простые отношения между родителями и детьми, которые выглядят так:

Почтовые серверы имеют n папок. Папки могут иметь n (под) папок. Папки имеют ссылку на свою родительскую папку, а также на сервер электронной почты, к которому они принадлежат.

Мои файлы сопоставления выглядят так:

MailServer.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 02.05.2011 12:32:52 by Hibernate Tools 3.3.0.GA -->
<hibernate-mapping>
    <class name="test.MailServer" table="MAILSERVER">

        <id name="id" type="long" access="field">
            <column name="MAIL_SERVER_ID" />
            <generator class="native" />
        </id>

        <bag name="folders" table="FOLDERS" lazy="false" inverse="true" cascade="all-delete-orphan">
            <key column="MAIL_SERVER_ID"></key>
            <one-to-many class="test.Folder" />
        </bag>

    </class>
</hibernate-mapping>

Folder.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 04.05.2011 15:02:31 by Hibernate Tools 3.3.0.GA -->
<hibernate-mapping>
    <class name="test.Folder" table="FOLDERS">

        <id name="id" type="long" access="field">
            <column name="FOLDER_ID" />
            <generator class="native" />
        </id>

        <many-to-one name="mailServer" column="MAIL_SERVER_ID" not-null="true" />

        <bag name="folders" table="FOLDERS" lazy="false" inverse="true" cascade="all">
            <key column="PARENT_FOLDER_ID" not-null="false"></key>
            <one-to-many class="test.Folder" />
        </bag>

        <many-to-one name="parentFolder" column="PARENT_FOLDER_ID" />

    </class>
</hibernate-mapping>

Проблема, с которой я столкнулся, заключается в следующем.

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

- MyMailServer
    Folder1
  - Folder2
      Subfolder
    Folder3

Когда я звоню hibernateSession.save(mailServerInstance); или hibernateSession.update(mailServerInstance);, Hibernate правильно сохраняет все в базе данных. Идентификаторы родительского столбца заполнены правильно. То же самое для всех других ссылок.

НО при загрузке данных Hibernate перезагружает иерархию папок следующим образом:

- MyMailServer
    Folder1
    Folder2
    Subfolder
    Folder3

Я понимаю причину: подпапка имеет ссылку на свой MailServer и, таким образом, Hibernate рекламирует ее там, а не в папке, к которой она принадлежит.

Но как мне решить эту проблему?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 03 июня 2011

Я обошел эту проблему, заменив

<bag name="folders" table="FOLDERS" lazy="false" inverse="true" cascade="all-delete-orphan">
    <key column="MAIL_SERVER_ID"></key>
    <one-to-many class="test.Folder" />
</bag>

в MailServer.hbm.xml на

<one-to-one name="rootFolder" class="test.Folder" cascade="all" />

Это помогло.

0 голосов
/ 09 мая 2011

Как вы уже поняли, что Hibernate делает здесь, логично, так как вы выбираете все папки для данного mailServer. Я не думаю, что есть способ достичь того, что вы хотите в одном запросе (без ограничения гибернации, также с простым старым SQL это невозможно). У меня очень похожий случай, когда я делаю следующее:

  1. получить корневые папки для почтового сервера (-> где родительская папка пуста)
  2. для каждой папки получаются дочерние папки

Другое решение заключается в использовании объектов переноса, и вы сопоставляете сущности объектам переноса, чтобы получить требуемую структуру.

Все зависит от вашего варианта использования, который (если таковой имеется) решение подходит. Например. если вы можете выполнять вызов AJAX каждый раз, когда папка раскрывается (древовидная структура), тогда первое решение идеально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...