Pregunta

Es bastante tiempo que estoy tratando de averiguar este problema y desde googlear alrededor muchas personas tienen problemas similares.

Estoy tratando de modelar un usuario en una red social, usando Hibernate, y lo que es más básico a una red social que asignar una relación de amistad? Cada usuario en el sistema debe tener una lista de amigos Es y pensé que esto podría ser una tarea increíblemente fácil (sólo tiene que utilizar una relación ManyToMany, ¿verdad?). Así que fui a probar lo siguiente:

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

El problema ahora es que me dice que use ManyToMany erróneamente por no tener clara distinción entre amigo y se hizo amigo. Hasta aquí todo bien, me sale el error, pero ¿cómo puedo hacer lo que quiero?

¿Alguna idea? He llegado al final de mi sabiduría.

¿Fue útil?

Solución

El hecho acerca de muchos a muchos es que se necesita un poco más de configuración, debido a su imperativo que Hibernate genera una tabla de relación. Prueba esto:


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

Espero que funcione =)

EDIT: Además, tenga mucho cuidado con ir a buscar tipos ... puede introducir un usuario ir a buscar bucle fuera de control y obtener toda la base de datos.

Otros consejos

La anotación ManyToMany tiene un parámetro mappedBy. Creo que algo así como

@ManyToMany(mappedBy = "friends")

podría funcionar. En cualquier caso, consulte la docs .

Editar:

Parece como si una relación muchos a muchos tiene que ser accesible desde ambos extremos. Actualmente la suya es sólo accesible desde un extremo. Tal vez se debe añadir la otra relación, así:

@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 eso no funciona, siempre se puede introducir una clase separada que representa la relación entre dos usuarios, y que cada usuario tiene un conjunto de instancias de esta clase.

Buen punto, y de hecho lo he intentado. El problema es que entonces consigo una queja sobre el atributo mappedBy se encuentra en ambos lados de la relación, lo cual es cierto, pero no es válido. Me preguntaba wether un simple @ManyToMany con alguna consulta personalizada inteligente para buscar a los amigos puede ser una solución: El ManyToMany generaría una tabla de unión con user_id y friend_id, pero la consulta se correspondería con cualquiera de los campos, volviendo todos los usuarios en ese partido, ya sea el friend_id o la user_id que es. ¿Alguna idea?

Esto, por supuesto, sería una buena solución, pero no estoy todavía completamente vendido. Básicamente para obtener los amigos que tendría que fusionar las dos colecciones, que es bastante insatisfactoria.

¿Hay absolutamente ninguna manera de crear un idempotente, relación reflexiva en hibernación?

Yo tenía el mismo problema hoy en día también.

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

debería estar bien, he usado una estructura similar. Sin embargo llegué excepciones carga lenta y cuando se ajusta el fetchType a Eager, llegué quejas sobre la inicialización recursiva de bolsas.

¿Cómo me fijo mi problema: En la consulta que se utiliza para buscar el 'usuario', hacer algo como:

from User as u left join fetch u.friends

Esto inicializar la lista de amigos de esa entidad. Se advierte sin embargo que no inicializar amigos de esos amigos. Eso es una buena cosa en realidad.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top