Question

Il est tout à fait un certain temps que j'essaie de comprendre ce problème et de googler autour de beaucoup de gens ont des problèmes similaires.

Je suis en train de modéliser un utilisateur dans un réseau social, en utilisant Hibernate, et ce qui est plus fondamental à un réseau social que de la carte une relation d'amitié? Chaque utilisateur du système devrait avoir une liste de c'est des amis et je pensais que cela pourrait être une tâche incroyablement facile (il suffit d'utiliser une relation ManyToMany, non?). Je suis donc allé à essayer ce qui suit:

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

Le problème est maintenant que cela me dit que j'utiliser ManyToMany à tort par l'absence de distinction claire entre ami et se lie d'amitié. Jusqu'à présent, si bon, je reçois l'erreur, mais comment puis-je faire ce que je veux?

Une idée? Je suis arrivé à la fin de ma sagesse.

Était-ce utile?

La solution

Le fait au sujet de plusieurs à plusieurs est qu'il a besoin d'un peu plus de configuration, car il est impératif que Hibernate génère une table de relation. Essayez ceci:


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

espérons que cela fonctionne =)

EDIT: Aussi, soyez très prudent avec les types chercher ... vous pouvez saisir un utilisateur aller chercher hors de contrôle en boucle et obtenir toutes les DB.

Autres conseils

L'annotation ManyToMany a un paramètre mappedBy. Je suppose que quelque chose comme

@ManyToMany(mappedBy = "friends")

pourrait fonctionner. Dans tous les cas, consultez la docs .

Edit:

Il semble que si plusieurs à plusieurs doit être accessible à partir des deux extrémités. À l'heure actuelle le vôtre est uniquement accessible d'un bout. Peut-être que vous devez ajouter l'autre relation ainsi:

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

Si cela ne fonctionne pas introduire, vous pouvez toujours une catégorie distincte représentant la relation entre deux utilisateurs, et que tous les utilisateurs ont une collection d'instances de cette classe.

Bon point, et en fait j'ai essayé. Le problème est que je puis obtenir une plainte sur l'attribut mappedBy étant mis sur les deux côtés de la relation, ce qui est vrai, mais invalide. Je me demandais wether simple @ManyToMany avec une requête personnalisée intelligente pour aller chercher les amis pourrait être une solution: Le ManyToMany générerait une table se joindre à user_id et friend_id, mais la requête correspondrait à l'un des champs, retournant tous les utilisateurs où ce match soit le friend_id ou user_id qui est. Toutes les idées?

Ce serait bien sûr une bonne solution, mais je ne suis pas encore complètement vendu. Fondamentalement, pour obtenir les amis que je devais fusionner les deux collections, ce qui est tout à fait insatisfaisante.

est-il absolument aucun moyen de créer un idempotent, relation réflexive en veille prolongée?

J'ai eu le même problème aujourd'hui aussi bien.

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

Devrait être ok, j'ai utilisé une structure similaire. Cependant, je suis des exceptions de chargement paresseux et lors du réglage du fetchType à Eager, je suis arrivé plaintes au sujet de l'initialisation récursive de sacs.

Comment je fixe mon problème: Dans la requête que vous utilisez pour chercher le « utilisateur », faire quelque chose comme:

from User as u left join fetch u.friends

initialisera la liste d'amis pour cette entité. Attention cependant qu'il n'initialise pas d'amis de ces amis. C'est une bonne chose en fait.

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