es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Existe alguna manera de mapear una relación simétrica bidireccional en Hibernate/JPA?

Me gustaría implementar una relación de amistad entre usuario en Hibernate/JPA, algo como:

class User {
     Set<User> amigos;
}

Digamos que el usuario A y el usuario B son amigos.
Si el usuario A deja de ser amigo del usuario B, la lista de amigos del usuario B no debería contener al usuario A.

¿Existe alguna forma clara de modelar este tipo de relación en Hibernate/JPA (y, por supuesto, en las tablas subyacentes de la base de datos)?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una forma limpia de modelar este tipo de relación en Hibernate/JPA. Esto se puede lograr implementando una relación bidireccional entre la clase User y sí misma a través del Set de amigos.

    En primer lugar, podemos anotar la clase de entidad User con la anotación @Entity para representarla como una entidad persistente. A continuación, creamos una relación ManyToMany entre User y friends con un atributo adicional llamado “inverseFriends” como se muestra a continuación:

    @Entity
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        @ManyToMany
        @JoinTable(
            name = "friends",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "friend_id")
        )
        private Set<user> friends = new HashSet<>();
    
        @ManyToMany(mappedBy = "friends")
        private Set<user> inverseFriends = new HashSet<>();
    
        // getters y setters
    }
    

    Note que los atributos friends e inverseFriends deben ser de tipo Set ya que estamos asociando múltiples usuarios entre sí.

    Cuando el Usuario A agrega al Usuario B como amigo, podemos usar el método addFriend() para agregar ambos usuarios a la lista de amigos del otro:

    public void addFriend(User friend) {
        this.friends.add(friend);
        friend.getInverseFriends().add(this);
    }
    

    De manera similar, cuando el Usuario A deja de ser amigo del Usuario B, podemos eliminar la referencia del Usuario B de la lista de amigos del Usuario A y la referencia del Usuario A de la lista de amigos inversa del Usuario B:

    public void removeFriend(User friend) {
        this.friends.remove(friend);
        friend.getInverseFriends().remove(this);
    }
    

    Con este enfoque, cuando el Usuario A deja de ser amigo del Usuario B, la lista de amigos del Usuario B ya no contendrá al Usuario A.

    En términos de tablas de base de datos, esta relación se implementará utilizando una tabla de unión llamada “friends” con user_id y friend_id como claves foráneas, donde cada fila representará una amistad entre dos usuarios.

Comments are closed.