2009-12-02 11 views
10

Ich habe eine Klasse Benutzer. Ein Benutzer kann ein Freund mit vielen anderen Benutzern sein. Die Beziehung ist gegenseitig. Wenn A ein Freund von B ist, dann ist B ein Freund von A. Ich möchte auch, dass jede Beziehung zusätzliche Daten speichert - zum Beispiel das Datum, an dem zwei Benutzer Freunde wurden. Dies ist also eine Viele-zu-Viele-Beziehung in derselben Tabelle mit zusätzlichen Spalten. Ich weiß, dass eine Freundschaft der Mittelschicht erstellt werden sollte (mit zwei Benutzer-IDs und einer Spalte für das Datum). Aber ich bin kurz damit, dies mit Hibernate zu kartieren. Die Sache, die mich daran hindert, ist, dass das Mapping auf dieselbe Tabelle erfolgt. Ich kann es lösen, wenn die Viele-zu-Viele-Beziehung zwischen zwei verschiedenen Tabellen besteht.Viele-zu-viele auf der gleichen Tabelle mit zusätzlichen Spalten

Antwort

7

Sie gesagt haben

many-to-many-Beziehung auf dem gleichen Tisch

Es ist keine gute Idee. Es ist ein Alptraum, den es zu pflegen gilt. Statt

@Entity 
public class Friend { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Integer friendId; 

    @Column 
    private String name; 

    @OneToMany(mappedBy="me") 
    private List<MyFriends> myFriends; 

} 

@Entity 
public class MyFriends { 

    @EmbeddedId 
    private MyFriendsId id; 

    @Column 
    private String additionalColumn; 

    @ManyToOne 
    @JoinColumn(name="ME_ID", insertable=false, updateable=false) 
    private Friend me; 

    @ManyToOne 
    @JoinColumn(name="MY_FRIEND_ID", insertable=false, updateable=false) 
    private Friend myFriend; 

    @Embeddable 
    public static class MyFriendsId implements Serializable { 

     @Column(name="ME_ID", nullable=false, updateable=false) 
     private Integer meId; 

     @Column(name="MY_FRIEND_ID", nullable=false, updateable=false) 
     private Integer myFriendId; 

     public boolean equals(Object o) { 
      if(o == null) 
       return false; 

      if(!(o instanceof MyFriendsId)) 
       return false; 

      MyFriendsId other = (MyFriendsId) o; 
      if(!(other.getMeId().equals(getMeId())) 
       return false; 

      if(!(other.getMyFriendId().equals(getMyFriendId())) 
       return false; 

      return true; 
     } 

     public int hashcode() { 
      // hashcode impl 
     } 

    } 


} 

Grüße

versuchen diese,

+0

Danke für Ihre Antwort. Aber ich habe eine Frage. Warum wird "insertable = false" in die @ManyToOne-Beziehungen eingefügt? Wenn ich es entferne, funktioniert es. Sonst wird die MyFriends nicht korrekt beibehalten. Ich bin kein Hibernate-Experte, also verstehe ich wahrscheinlich nichts. –

+0

Ok, ich habe keine EmbeddedId wie Sie verwendet, sondern nur eine weitere ID-Spalte. Sie haben das insertable = false gesetzt, weil sich die EmbeddedId darum kümmert. Ihre Antwort wird angenommen :) –

+0

Sie haben bemerkt warum. Wenn zwei Eigenschaften dieselbe Spalte verwenden, empfiehlt es sich, Einstellungen nur in einer Eigenschaft vorzunehmen. Andernfalls wird Hibernate einige Fehler melden. –

2

Ich bin mir nicht sicher, dass dies zu Ihrem Fall passt, aber versuchen Sie es.

@Entity 
public class Friend { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private int friendId; 

    @Column 
    private String name; 

    @ManyToMany(mappedBy="owner") 
    private List<Friendship> friendships; 
} 

@Entity 
public class Friendship { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private int friendshipId; 

    @OneToOne 
    private Friend owner; 

    @OneToOne 
    private Friend target; 

    // other info 
} 
1

Ich hatte das gleiche Problem. Sie können etwas wie dieses versuchen:

<class name="Friend" entity-name="RelatedFriend" table="FRIENDS"> 
    <id name="id" type="long"> 
     <generator class="native" /> 
    </id> 

    <!-- *** --> 

    <set name="relatedFriends" table="RELATED_FRIENDS"> 
     <key column="FRIEND_ID" /> 
     <many-to-many column="RELATED_FRIEND_ID" class="Friend" entity-name="RelatedFriend"/> 
    </set> 
</class> 
Verwandte Themen