2010-09-28 3 views
1

Привет Я пытаюсь отобразить некоторые классы в спящем режиме и имею общую проблему, как такое сопоставление можно сделать. Существует класс пользователей и Facebook пользовательский класс, который имеет следующую структуру Класс пользователя:Сопоставление такого же отношения классов

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

Facebook класс FbUser может иметь список друзей, которые являются объектами одного и того же класса FbUser.

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

До сих пор я делал много отношений между пользователем и 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> 

А теперь 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 можно отобразить FbUser Список внутри FbUser файл карты? Я заблудился :(

ответ

2

Вы можете создать дополнительный класс с именем, например, MyFriends

public class FbUser { 

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

} 

Просто соответствующая часть

Если у вас есть индекс колонки

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

Если у вас нет индекса колонки

повторно написать свой список как

public class FbUser { 

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

} 

И

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

И ваше отображение MyFriends. Обратите внимание, что вам нужно составной первичный ключ (реализован как статический внутренний класс)

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

Ваш MyFriends отображается следующим образом

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

Привет, Ваше решение завораживает. Однако не могли бы вы объяснить, почему я должен использовать коллекцию вместо List, если у меня нет строки индекса? и зачем мне нужен составной первичный ключ? –

+0

@ danny.lesnik Если вы используете Список, Hibernate будет жаловаться, что у вас нет столбца индекса. Смотрите здесь почему: http://stackoverflow.com/questions/3580686/hibernate-one-to-many-mapping-works-with-a-list-but-not-a-set/3580835#3580835 Вам нужен составной первичный потому что ваши отношения ManyToMany «были разделены» на отношения OneToMany. Когда отношения ManyToMany разделяются на OneToMany, ** вам нужен составной первичный ключ **. ManyToMany похож на OneToMany (с составным первичным ключом) –

+0

@ danny.lesnik Имейте в виду, что решение, предоставленное @Plinio Pantaleão, также отлично работает. Но он использует набор.Предпочитаете использовать пакет вместо **, если у вас нет согласованного метода equals и hashCode ** В противном случае вы можете получить неожиданное поведение. –

2

Ну, во-первых: Пользователь имеет взаимно-однозначное отношение с FbUser, правильно? second: Карта FbUser для FbUser как отношение многих ко многим, используя список или набор. Установить пример здесь:

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