Многие ко многим в одной таблице с дополнительными столбцами - PullRequest
10 голосов
/ 02 декабря 2009

У меня есть класс User. Пользователь может быть другом со многими другими пользователями. Отношения взаимны. Если A - друг B, то B - друг A. Кроме того, я хочу, чтобы все отношения хранили дополнительные данные - например, дату, когда два пользователя стали друзьями. Так что это отношение «многие ко многим» в одной таблице с дополнительными столбцами. Я знаю, что дружба среднего класса должна быть создана (содержит два идентификатора пользователя и столбец для даты). Но я не собираюсь отображать это с помощью Hibernate. Что меня останавливает, так это то, что сопоставление происходит с одной и той же таблицей. Я могу решить это, если бы отношение «многие ко многим» было между двумя разными таблицами.

Ответы [ 3 ]

7 голосов
/ 02 декабря 2009

Вы сказали

отношение «многие ко многим» на одном столе

Это не очень хорошая идея. Это кошмар для поддержания.

Попробуйте вместо этого

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

    }


}

С уважением,

3 голосов
/ 02 декабря 2009

Я не уверен, что это подойдет вам, но попробуйте.

@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 голос
/ 02 мая 2010

У меня была такая же проблема.Вы можете попробовать что-то вроде этого:

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