Hibernate:如何建模双父/子关系

时间:2011-05-09 11:17:17

标签: java hibernate

我在这里有一个非常简单的父/子关系,看起来像这样:

电子邮件服务器有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会正确地将所有内容存储到数据库中。父列id已正确填充。所有其他参考文献也是如此。

但是当我加载数据时,Hibernate重新加载文件夹层次结构如下:

- MyMailServer
    Folder1
    Folder2
    Subfolder
    Folder3

我理解原因:子文件夹有一个对其MailServer的引用,因此,Hibernate在那里广告而不是它所属的文件夹。

但是,我该如何解决这个问题?

提前致谢!

2 个答案:

答案 0 :(得分:0)

正如您已经了解Hibernate在这里所做的那样是合乎逻辑的,因为您正在获取给定mailServer的所有文件夹。我不认为有一种方法可以在一个单一查询中实现你想要的东西(不是hibernate限制,也不是普通的旧SQL,这是不可能的)。 我有一个非常类似的情况,我会做以下事情:

  1. 获取邮件服务器的根文件夹( - &gt;,其中父文件夹为空)
  2. 为每个文件夹获取子文件夹
  3. 另一种解决方案是使用传输对象,然后将实体映射到传输对象,以便获得所需的结构。

    这完全取决于您的使用案例(如果有的话)是否合适。例如。如果你可以在每次扩展文件夹时执行AJAX调用(树结构),那么第一个解决方案是理想的。

答案 1 :(得分:0)

我通过替换

解决了这个问题
<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" />

这就是诀窍。