Question

Je suis en train de concevoir une sorte d'utilisateur à la relation utilisateur, tels que « l'utilisateur A fait suite à l'utilisateur B » et « utilisateur A veut être l'ami de l'utilisateur B ».

J'ai une classe d'utilisateurs, et la façon dont il est conçu ressemble à ceci:

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

}

Je suis en cours d'exécution en deux problèmes:

  • Mise en veille prolongée me donne ne peut pas chercher simultanément plusieurs sacs problème
  • J'ai regardé en ligne, les gens ont dit d'enlever FetchType.EAGER ou changer pour définir la place de la liste, mais qui me ont donné lieu n'a pas de valeur par défaut

J'ai le sentiment que la relation ne se définit pas correctement, et aussi je devrais voir plus de tables, parce qu'en ce moment, je ne vois que la table utilisateur, et une table User_User.


Mise à jour

Ce qui suit crée 3 tables, amis, disciples, et les demandeurs. Est-ce un peu optimisé par rapport à 5 tables? Et y at-il un avantage à ce par rapport à ce que Mr.J4mes suggéré?

@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;
Était-ce utile?

La solution

Tout d'abord, pour mettre en œuvre votre fonction, vous devez utiliser @ManyToMany au lieu de @OneToMany. Il devrait ressembler à ceci:

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

Vos relations ressemble les bidirectionnels à moi. Si vous utilisez @OneToMany, cela signifie que C has 2 followers A and B = A and B only follows C. Cependant, le fait est qu'une personne peut suit beaucoup de gens et une personne peut être suivie par de nombreuses personnes. En d'autres termes, A and B can also follow D.

En outre, vous ne devriez pas utiliser cascadeType.ALL du tout. Cela signifie que la politique en cascade que si un utilisateur supprime son compte et vous supprimez l'entrée correspondante dans la base de données, tous ses amis, etc. seront également supprimés.

Autres conseils

Hibernate ne génère une table pour l'entité utilisateur, et je suppose une table de référence croisée pour l'utilisateur de la relation utilisateur. Solution d'avoir des tables différentes peut-être avoir différentes entités configuration pour les différentes relations i.e..

Entité Utilisateur

@OneToMany
List<Follower> followers;

Suiveur Entité

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

@Id
@Generated
int id;

En ce qui concerne l'extraction Eager, vous pourriez effectivement voulez tous ceux qui doivent être LAZY, en raison du fait que, selon la façon dont votre base de données est mis en place, toutes ces charges pourrait être désireux assez cher. Seulement lorsque l'utilisateur veut charger les adeptes des utilisateurs, ce que je veux les chercher.

Séparer la User d'essayer de Friends faire une table avec au moins 2 colonnes qui mappe le User_ID à toute sa Friends_IDs qui est essentiellement une référence à User_ID

En outre EAGER se charge ALL les données dès que vous l'appelez la première fois. Les moyens il charge tous les utilisateurs et leurs amis. amis de chargement doivent être LAZY, à savoir chargé uniquement lorsque vous en avez besoin.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top