Pergunta

É bastante tempo que eu estou tentando descobrir este problema e de pesquisando em torno muitas pessoas têm problemas semelhantes.

Eu estou tentando modelar um usuário em uma rede social, usando o Hibernate, eo que é mais básico para uma rede social do que para mapear uma relação de amizade? Cada usuário no sistema deve ter uma lista de seu amigos e eu pensei que isso pode ser uma tarefa extremamente fácil (basta usar uma relação ManyToMany, certo?). Então eu fui para tentar o seguinte:

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

O problema agora é que ele me Eu uso ManyToMany diz erroneamente por ter nenhuma distinção clara entre amigo e amigo. Até aí tudo bem, eu recebo o erro, mas como eu posso fazer o que eu quero?

Alguma idéia? Cheguei ao fim de minha sabedoria.

Foi útil?

Solução

O fato sobre muitos para muitos é que ele precisa de um pouco de configuração mais, porque é imperativo que o Hibernate gera uma tabela de relação. Tente isto:


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

Hope funciona =)

EDIT: Além disso, ter muito cuidado com buscar tipos ... você pode inserir um usuário buscar loop out-of-control e obter todas as DB.

Outras dicas

A anotação ManyToMany tem um parâmetro mappedBy. Eu acho que algo como

@ManyToMany(mappedBy = "friends")

trabalho poder. Em todo o caso, consulte a docs .

Editar:

Parece que a muitos para muitos necessidades de relacionamento para ser acessível a partir de ambas as extremidades. Atualmente o seu é acessível apenas de um lado. Talvez você deve adicionar a outra relação, bem como:

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

Se isso não funcionar, você sempre pode introduzir uma classe separada que representa a relação entre dois usuários, e cada usuário tem uma coleção de instâncias desta classe.

Bom ponto, e na verdade eu tentei isso. O problema é que eu então, fazer uma reclamação sobre a mappedBy atributo a ser definido em ambos os lados da relação, o que é verdade, mas inválido. Fiquei me perguntando wether uma simples @ManyToMany com alguma consulta personalizada inteligente para buscar os amigos pode ser uma solução: O ManyToMany geraria uma junção mesa com user_id e friend_id, mas a consulta iria coincidir com qualquer um dos campos, retornando todos os usuários, onde a partida ou o friend_id ou o user_id que é. Alguma idéia?

Isso, claro, seria uma boa solução, mas eu ainda não estou completamente vendido. Basicamente para obter os amigos que eu teria que mesclar as duas coleções, que é bastante insatisfatória.

Existe absolutamente nenhuma maneira de criar um idempotent, relação reflexiva em hibernação?

Eu tive o mesmo problema hoje também.

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

Deve ser ok, eu usei uma estrutura similar. No entanto eu tenho exceções carregamento lento e ao definir o fetchType para EAGER, eu tenho queixas sobre a inicialização recursiva de sacos.

Como eu fixo meu problema: Na consulta que você usa para buscar o 'user', fazer algo como:

from User as u left join fetch u.friends

Isto irá inicializar a lista de amigos para essa entidade. Lembre que ele não inicializar todos os amigos a partir desses amigos. Isso é uma coisa boa, na verdade.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top