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
10
A
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,
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>
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. –
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 :) –
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. –