Hibernate @OneToMany отображение отношений - PullRequest
0 голосов
/ 12 января 2012

Я пытаюсь создать какое-то отношение пользователя к пользователю, такое как «пользователь A следует за пользователем B» и «пользователь A хочет быть другом пользователя B».

У меня есть класс пользователя, ивыглядит так:

@Entity
public class User{
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> followers;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> following;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> friendRequests;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> requesting;
    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    List<User> friends;

}

У меня две проблемы:

  • Hibernate дает мне не может одновременно получить несколько пакетов проблема
  • Я посмотрел в Интернете, люди сказали, чтобы удалить FetchType.EAGER или изменить его на Set вместо List, но это привело меня Поле не имеет значения по умолчанию

У меня такое ощущение, что отношения не определены должным образом, а также я должен видеть больше таблиц, потому что сейчас я вижу только таблицу User и таблицу User_User.

Обновление

Следующее создает 3 таблицы, друзей, подписчиков и запросчиков.Это несколько оптимизировано по сравнению с 5 таблицами?И есть ли какое-то преимущество в этом по сравнению с тем, что предложил Mr.J4mes?

@ManyToMany
@JoinTable(name = "followers", joinColumns = @JoinColumn(name = "followerId"), inverseJoinColumns = @JoinColumn(name = "userId"))
private List<User> followers;
@ManyToMany
@JoinTable(name = "followers", joinColumns = @JoinColumn(name = "userId"), inverseJoinColumns = @JoinColumn(name = "followerId"))
private List<User> following;
@ManyToMany
@JoinTable(name = "friends", joinColumns = @JoinColumn(name = "userId"), inverseJoinColumns = @JoinColumn(name = "friendId"))
private List<User> friends;
@ManyToMany
@JoinTable(name = "requesters", joinColumns = @JoinColumn(name = "requesterId"), inverseJoinColumns = @JoinColumn(name = "userId"))
private List<User> friendRequests;
@ManyToMany
@JoinTable(name = "requesters", joinColumns = @JoinColumn(name = "userId"), inverseJoinColumns = @JoinColumn(name = "requesterId"))
private List<User> requesting;

Ответы [ 3 ]

1 голос
/ 12 января 2012

Прежде всего, для реализации вашей функции вы должны использовать @ManyToMany вместо @OneToMany.Это должно выглядеть так:

@Entity
public class User implements Serializable {
   @ManyToMany(mappedBy="followers")
   @JoinTable(name="followingTable")
   private Set<User> following;
   @ManyToMany
   @JoinTable(name="followerTable")
   private Set<User> followers;
   @ManyToMany(mappedBy="friendRequests")
   @JoinTable(name="requestingTable")
   private Set<User> requesting;
   @ManyToMany
   @JoinTable(name="friendRequestTable")
   private Set<User> friendRequests;
   @ManyToMany
   private Set<User> friends;
}

Ваши отношения для меня выглядят как двунаправленные.Если вы используете @OneToMany, это означает, что C has 2 followers A and B = A and B only follows C.Однако факт заключается в том, что один человек может следовать за многими людьми, а один человек может следовать за многими людьми.Другими словами, A and B can also follow D.

Кроме того, вы вообще не должны использовать cascadeType.ALL.Эта каскадная политика означает, что если один пользователь удалит свою учетную запись и вы удалите соответствующую запись в базе данных, все его друзья и т. Д. Также будут удалены.

0 голосов
/ 12 января 2012

Отделите User от Friends и попытайтесь составить таблицу, содержащую не менее 2 столбцов, которая сопоставит User_ID со всеми его Friends_IDs, что в основном является ссылкой на User_ID

Также EAGER загрузит ALL данные, как только вы вызовете их в первый раз. Значит, это загрузит всех пользователей и их друзей Загрузка друзей должна быть LAZY, т.е. загружаться только тогда, когда они вам нужны.

0 голосов
/ 12 января 2012

Hibernate сгенерирует только одну таблицу для объекта «Пользователь», и я предполагаю таблицу перекрестных ссылок для отношения «Пользователь-пользователь». Обходной путь для наличия разных таблиц может иметь разные сущности, настроенные для разных отношений, т.е.

Пользовательский объект

@OneToMany
List<Follower> followers;

Подписчик Entity

@Entity
class Follower
...
@ManyToOne
User user;

@Id
@Generated
int id;

Что касается извлечения EAGER, вы, возможно, захотите, чтобы все они были LAZY, потому что в зависимости от того, как настроена ваша база данных, все эти загружаемые нагрузки могут быть довольно дорогими. Только когда пользователь захочет загрузить подписчиков пользователей, я захочу получить их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...