2011-05-09 4 views
1

Je suis une relation parent assez simple/enfant ici, qui ressemble à ceci:: Comment modéliser une double relation parent/enfant

serveurs de messagerie ont n dossiers. Les dossiers peuvent contenir n (sous-) dossiers. Les dossiers renvoient à leur dossier parent ainsi qu'au serveur de messagerie auquel ils appartiennent.

Mes fichiers de mappage ressembler à ceci:

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> 

Le problème que je suis, est Suivant.

Disons que, je le hierachy suivant:

- MyMailServer 
    Folder1 
    - Folder2 
     Subfolder 
    Folder3 

Quand j'appelle hibernateSession.save(mailServerInstance); ou hibernateSession.update(mailServerInstance);, Hibernate stocke correctement tout à la base de données. Les identifiants de colonnes parents sont remplis correctement. Idem pour toutes les autres références.

MAIS quand je charge les données, Hibernate rechargements le dossier hierachy comme ceci:

- MyMailServer 
    Folder1 
    Folder2 
    Subfolder 
    Folder3 

Je comprends la raison: Subfolder a une référence à son MailServer et donc, Hibernate annonces là au lieu de dossier où il appartient.

Mais comment résoudre ce problème?

Merci d'avance!

+0

Je crois que ce que vous cherchez n'est pas nécessairement une relation parent-enfant autant qu'une relation plusieurs-à-plusieurs. Ceux-ci sont difficiles tant du point de vue de la base de données que du point de vue de la modélisation. –

+0

Etes-vous sûr? Si mailserver peut avoir plusieurs dossiers, mais que les dossiers ne peuvent appartenir qu'à un seul serveur de messagerie, que ce soit un-à-plusieurs ou pas? Idem pour les dossiers et (sous-) dossiers. Un dossier peut avoir plusieurs sous-dossiers mais seulement un dossier parent (au maximum), donc ce serait aussi un-à-plusieurs, à mon avis. – Timo

+0

Désolé j'ai mal lu ce que vous disiez. –

Répondre

0

J'ai travaillé autour de ce en remplaçant

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

dans MailServer.hbm.xml avec

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

Cela a fait l'affaire.

0

Comme vous avez déjà compris ce que Hibernate fait ici est logique puisque vous récupérez tous les dossiers pour mailServer donné. Je ne pense pas qu'il existe un moyen d'atteindre ce que vous voulez dans une seule requête (pas une restriction d'hibernation, aussi avec du vieux SQL simple ce n'est pas possible). J'ai un cas très similaire où je fais ce qui suit:

  1. get dossiers racine pour le serveur de messagerie (-> où dossier parent est null)
  2. pour chaque dossier obtenir les dossiers enfants

Une autre solution consiste à utiliser des objets de transfert et à mapper les entités aux objets de transfert afin que la structure requise soit obtenue.

Tout dépend de votre cas d'utilisation quelle solution (le cas échéant) est appropriée. Par exemple. Si vous pouvez exécuter un appel AJAX chaque fois qu'un dossier est développé (arborescence), la première solution est idéale.

+0

Donc, vous suggérez de faire la différence entre les dossiers racines et les dossiers non-root, non? Cela voudrait dire que j'ai besoin de stocker chaque type de dossier dans sa propre table, ou pas? – Timo

+0

Non, qu'est-ce qu'un dossier racine? Un dossier qui n'a pas de dossier parent? Qu'est-ce qu'un sous-dossier? Un dossier qui a un dossier parent. Cette différence peut être vue en utilisant SQL/Hibernate. –

+0

Euh, comment devrais-je modifier mes fichiers hbm.xml alors? Parce que la façon dont ils sont maintenant, parent est soit nul ou non (donc c'est sauvegardé correctement) mais de toute évidence cela ne fonctionne pas. – Timo

Questions connexes