2011-05-09 40 views
1

我来到这里一个非常简单的父/子关系,它看起来像这样:休眠:如何模拟双父/子关系

电子邮件服务器有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);,休眠正确地把所有东西到数据库中。父列ID被正确填充。相同的所有其他参考。

当我加载数据时,Hibernate重新加载文件夹层次结构是这样的:

- MyMailServer 
    Folder1 
    Folder2 
    Subfolder 
    Folder3 

我明白其中的道理:子文件夹有其邮件服务器的参考,因此,Hibernate的广告在那儿,而不是文件夹所在的位置。

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

在此先感谢!

+0

我相信你所寻找的不一定是一对多的亲子关系。从数据库角度以及建模角度来看,这些都很棘手。 – 2011-05-09 12:11:33

+0

你确定吗?如果邮件服务器可以有多个文件夹,但文件夹只能属于一个邮件服务器,那么这是一对多还是不是?文件夹和(子)文件夹相同。一个文件夹可以有多个子文件夹,但只有一个父文件夹(最多),所以这在我看来也是一对多的。 – Timo 2011-05-09 14:59:55

+0

对不起,我误解你在说什么。 – 2011-05-09 18:14:09

回答

0

我工作围绕这在MailServer.hbm更换

<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> 

。xml with

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

这样做了。

0

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

  1. 获得root文件夹的邮件服务器( - >其中的父文件夹为空)
  2. 每个文件夹获取子文件夹

另一个解决方案是使用传输对象,并将实体映射到传输对象,以便获得所需的结构。

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

+0

所以,你建议区分根文件夹和非根文件夹,对吧?这意味着我需要将每个文件夹类型存储在自己的表中,或者不是? – Timo 2011-05-09 12:35:37

+0

不,什么是根文件夹?没有父文件夹的文件夹?什么是子文件夹?具有父文件夹的文件夹。使用SQL/Hibernate可以看出这种差异。 – 2011-05-09 12:36:49

+0

呃,用什么方法可以修改我的hbm.xml文件呢?因为他们现在的方式,父母是否为null(所以这是正确保存),但显然它不工作。 – Timo 2011-05-09 13:15:59