2010-09-28 4 views
1

Salut J'essaie de mapper certaines classes en mode hibernation là-bas et j'ai un problème général quant à la façon dont un tel mappage peut être effectué. Il est classe User et Facebook classe utilisateur qui a la structure suivante classe utilisateur:Mappage de la même relation de classe

public class User{ 
public User(){} 
Long Id; 
String FirstName; 
String LastName; 
.... 
FbUser fbuser; 
//// all requred 
getters and setters... 
} 

Facebook classe FbUser peut avoir la liste des amis qui sont des objets de la même classe FbUser.

public class FbUser{ 
public FbUser(){} 
Long fbId; 
String FirstName; 
String LastName; 
List<FbUser> friends; 
//// all requred 
getters and setters... 
} 

Jusqu'à présent, j'ai fait beaucoup à une relation entre utilisateur et FbUser.

<hibernate-mapping> 
    <class 
     name="User" 
     table="User" 
    > 

     <id 
      name="Id" 
      column="ID" 
      type="java.lang.Long" 
      unsaved-value="null" 
     > 
     <generator class="increment"/> 
     </id> 

     <property 
      name="FirstName" 
      update="true" 
      insert="true" 
      not-null="false" 
      unique="false" 
      type="java.lang.String" 
     > 
      <column name="FirstName" /> 
     </property> 
<property 
      name="LastName" 
      update="true" 
      insert="true" 
      not-null="false" 
      unique="false" 
      type="java.lang.String" 
     > 
      <column name="LastName" /> 
     </property> 
     <many-to-one 
      name="fbUser" 
      class="FbUser" 
      cascade="all" 
      column="fbId" 
      unique="true" 
     /> 

    </class> 
</hibernate-mapping> 

Et maintenant, le FbUser Mapping:

<hibernate-mapping> 
    <class 
     name="FbUser" 
     table="FbUser" 
    > 

     <id 
      name="fbId" 
      column="fbId" 
      type="java.lang.Long" 
      unsaved-value="null" 
     > 
      <generator class="increment"/> 
     </id> 

     <property 
      name="FirstName" 
      update="true" 
      insert="true" 
      not-null="false" 
      unique="false" 
      type="java.lang.String" 
     > 
      <column name="FirstName" /> 
     </property> 

     <property 
      name="LastName" 
      type="java.lang.String" 
      update="true" 
      insert="true" 
      column="LastName" 
      not-null="true" 
      unique="false" 
     /> 
    </class> 
</hibernate-mapping> 

Chow puis-je la carte FbUser Liste dans la carte FbUser fichier? Je me suis perdu :(

Répondre

2

Vous pouvez créer une classe supplémentaire nommée, par exemple, MyFriends

public class FbUser { 

    List<MyFriends> friends = new ArrayList<MyFriends>(); 

} 

Juste partie pertinente

Si vous avez un index de colonne

<hibernate-mapping> 
    <class name="FbUser"> 
     <list name="myFriends"> 
      <key column="ME_ID" insert="false" update="false"/> 
      <list-index column="WHICH COLUMN SHOULD BE USED AS INDEX"/> 
      <one-to-many class="MyFriends"/> 
     </list> 
    </class> 
</hibernate-mapping> 

Si vous ne disposez pas d'un index de colonne

réécrivez votre liste comme

public class FbUser { 

    Collection<MyFriends> friends = new ArrayList<MyFriends>(); 

} 

Et

<hibernate-mapping> 
    <class name="FbUser"> 
     <bag name="columns"> 
      <key column="ME_ID" insert="false" update="false"/> 
      <one-to-many class="MyFriends"/> 
     </bag> 
    </class> 
</hibernate-mapping> 

Et votre mapping MyFriends. Avis vous avez besoin d'une clé primaire composite (mis en œuvre en tant que classe interne statique)

<class name="MyFriends"> 
    <composite-id name="myFriendsId" class="MyFriends$MyFriendsId"> 
     <key-property name="meId"/> 
     <key-property name="myFriendId"/> 
    </composite-id> 
    <many-to-one name="me" class="FbUser" insert="false" update="false"/> 
    <many-to-one name="myFriend" class="FbUser" insert="false" update="false"/> 
</class> 

Votre MyFriends est présentée comme suit

public class MyFriends { 

    private MyFriendsId myFrinedId; 

    private FbUser me; 
    private FbUser myFriend; 

    public static class MyFriendsId implements Serializable { 

     private Integer meId; 
     private Integer myFriendId; 

     // getter's and setter's 

     public MyFriendsId() {} 
     public MyFriendsId(Integer meId, Integer myFriendId) { 
      this.meId = meId; 
      this.myFriendId = myFriendId; 
     } 

     // getter's and setter's 

     public boolean equals(Object o) { 
      if(!(o instanceof MyFriendsId)) 
       return false; 

      MyFriendsId other = (MyFriendsId) o; 
      return new EqualsBuilder() 
         .append(getMeId(), other.getMeId()) 
         .append(getMyFriendId(), other.getMyFriendId()) 
         .isEquals(); 
     } 

     public int hashcode() { 
      return new HashCodeBuilder() 
         .append(getMeId()) 
         .append(getMyFriendId()) 
         .hashCode(); 
     } 
    } 
} 
+0

Salut, Votre solution est fascinante. Cependant pourriez-vous s'il vous plaît expliquer pourquoi devrais-je utiliser la collection à la place Liste si je n'ai pas la ligne d'index? et pourquoi ai-je besoin d'une clé primaire composite? –

+0

@ danny.lesnik Si vous utilisez une liste, Hibernate se plaindra que vous n'avez pas de colonne d'index. Voir ici pourquoi: http://stackoverflow.com/questions/3580686/hibernate-one-to-many-mapping-works-with-a-list-but-not-a-set/3580835#3580835 Vous avez besoin d'un primaire composite clé parce que votre relation ManyToMany "a été divisée" en une relation OneToMany. Quand une relation ManyToMany est divisée en OneToMany, ** vous avez besoin d'une clé primaire composite **. ManyToMany est similaire à OneToMany (avec une clé primaire composite) –

+0

@ danny.lesnik Gardez à l'esprit la solution fournie par @Plinio Pantaleão fonctionne également très bien. Mais il utilise un ensemble.Préférez utiliser un sac à la place ** si vous n'avez pas de méthode equals et hashCode cohérente ** Sinon, vous pouvez avoir un comportement inattendu. –

2

Eh bien, d'abord: Utilisateur a une relation un-à-un avec FbUser, correcte? deuxième: Mapper FbUser à FbUser comme une relation de plusieurs à plusieurs en utilisant une liste ou un ensemble. Set exemple ici:

<set 
     name="friends" 
     table="FbUser" <!-You may use other table here if you want-> 
     access="field"> 
     <key 
      column="fbId"/> 
     <many-to-many 
      class="bla.bla.bla.FbUser" 
      column="friend_id" /> 
    </set> 
Questions connexes