Впадать в спящий режим:Отображение отношений между пользователями и Друзьями в социальных сетях

StackOverflow https://stackoverflow.com/questions/396391

Вопрос

Прошло довольно много времени, пока я пытаюсь разобраться в этой проблеме, и, погуглив, многие люди сталкиваются с подобными проблемами.

Я пытаюсь смоделировать пользователя в социальной сети, используя Hibernate, а что может быть более базовым для социальной сети, чем отображение дружеских отношений?У каждого пользователя в системе должен быть список своих друзей, и я подумал, что это может быть невероятно простой задачей (просто используйте отношение ManyToMany, верно?).Поэтому я решил попробовать следующее:

@Entity
@Table(name="users")
public class User {
   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   @Column(name="userid")
   protected Long id = null;
   @ManyToMany
   protected List<User> friends = null
}

Проблема сейчас в том, что это говорит мне, что я неправильно использую ManyToMany, не имея четкого различия между friend и befriended .Пока все хорошо, я получаю сообщение об ошибке, но как я могу делать то, что я хочу?

Есть какие-нибудь идеи?Я достиг предела своей мудрости.

Это было полезно?

Решение

Факт о многих ко многим заключается в том, что ему требуется немного больше настроек, потому что обязательно, чтобы Hibernate генерировал таблицу отношений.Попробуй это:


@Entity
@Table(name="users")
public class User {
   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   @Column(name="userid")
   protected Long id = null;
   @ManyToMany
   @JoinTable(name = "user_friends", 
       joinColumns = @JoinColumn(name = "user_id"), 
       inverseJoinColumns = @JoinColumn(name = "friend_id"))
   protected List friends = null;
   @ManyToMany(mappedBy = "friends")
   protected List befriended = null;
}

Надеюсь, это сработает =)

Редактировать:Кроме того, будьте очень осторожны с типами выборки...вы можете войти в неконтролируемый цикл выборки пользователя и получить всю базу данных.

Другие советы

В ManyToMany аннотация имеет параметр mappedBy.Я предполагаю, что что-то вроде

@ManyToMany(mappedBy = "friends")

может сработать.В любом случае, смотрите Документы.

Редактировать:

Кажется, что отношения "многие ко многим" должны быть доступны с обоих концов.В настоящее время ваш доступен только с одного конца.Может быть, вам следует добавить и другое отношение:

@Entity
@Table(name="users")
public class User {
   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   @Column(name="userid")
   protected Long id = null;
   @ManyToMany
   protected List<User> friends = null;
   @ManyToMany(mappedBy = "friends")
   protected List<User> befriended = null;
}

Если это не сработает, вы всегда можете ввести отдельный класс, представляющий связь между двумя пользователями, и позволить каждому пользователю иметь коллекцию экземпляров этого класса.

Хороший довод, и на самом деле я это пробовал.Проблема в том, что затем я получаю жалобу на то, что атрибут mappedBy установлен на обеих сторонах отношения, что верно, но недопустимо.Мне было интересно, будет ли простой @ManyToMany с помощью какого-нибудь умного пользовательского запроса поиск друзей мог бы стать решением:В ManyToMany сгенерировал бы таблицу объединения с user_id и friend_id, но запрос будет соответствовать любому из полей, возвращая всех пользователей, где это соответствует либо friend_id или тот user_id то есть.Есть какие-нибудь идеи?

Это, конечно, было бы хорошим решением, но я еще не полностью продан.По сути, чтобы привлечь друзей, мне пришлось бы объединить две коллекции, что довольно неудовлетворительно.

Неужели нет абсолютно никакого способа создать идемпотентное, рефлексивное отношение в hibernate?

Сегодня у меня тоже была такая же проблема.

@Entity
@Table(name="users")
public class User {
   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   @Column(name="userid")
   protected Long id = null;
   @ManyToMany
   protected List<User> friends = null
}

Должно быть в порядке, я использовал аналогичную структуру.Однако я получил исключения отложенной загрузки, и при установке FetchType на EAGER я получил жалобы на рекурсивную инициализацию пакетов.

Как я устранил свою проблему:В запросе, который вы используете для получения "пользователя", сделайте что-то вроде:

from User as u left join fetch u.friends

Это инициализирует список друзей для этого объекта.Однако имейте в виду, что он не инициализирует никаких друзей из этих друзей.На самом деле это хорошо.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top