Saltar al contenido

¿Cómo eliminar la entidad con la relación ManyToMany en JPA (y las filas de la tabla de unión correspondientes)?

Solución:

  • La propiedad de la relación está determinada por el lugar donde coloque el atributo ‘mappedBy’ en la anotación. La entidad que pones ‘mappedBy’ es la que NO es el propietario. No hay posibilidad de que ambas partes sean dueñas. Si no tiene un caso de uso de ‘eliminar usuario’, simplemente puede mover la propiedad al Group entidad, ya que actualmente User es el dueño.
  • Por otro lado, no ha estado preguntando al respecto, pero hay una cosa que vale la pena saber. los groups y users no se combinan entre sí. Quiero decir, después de eliminar la instancia de User1 de Group1.users, las colecciones de User1.groups no se cambian automáticamente (lo cual es bastante sorprendente para mí),
  • Considerándolo todo, le sugiero que decida quién es el propietario. Digamos el User es el dueño. Luego, al eliminar un usuario, la relación usuario-grupo se actualizará automáticamente. Pero al eliminar un grupo, debes encargarte de eliminar la relación tú mismo de esta manera:

entityManager.remove(group)
for (User user : group.users) {
     user.groups.remove(group);
}
...
// then merge() and flush()

Lo siguiente funciona para mí. Agregue el siguiente método a la entidad que no es propietaria de la relación (Grupo)

@PreRemove
private void removeGroupsFromUsers() {
    for (User u : users) {
        u.getGroups().remove(this);
    }
}

Tenga en cuenta que para que esto funcione, el Grupo debe tener una lista actualizada de Usuarios (lo cual no se hace automáticamente). por lo que cada vez que agrega un Grupo a la lista de grupos en la entidad Usuario, también debe agregar un Usuario a la lista de usuarios en la entidad Grupo.

Encontré una posible solución, pero … no sé si es una buena solución.

@Entity
public class Role extends Identifiable {

    @ManyToMany(cascade ={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    @JoinTable(name="Role_Permission",
            [email protected](name="Role_id"),
            [email protected](name="Permission_id")
        )
    public List<Permission> getPermissions() {
        return permissions;
    }

    public void setPermissions(List<Permission> permissions) {
        this.permissions = permissions;
    }
}

@Entity
public class Permission extends Identifiable {

    @ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
    @JoinTable(name="Role_Permission",
            [email protected](name="Permission_id"),
            [email protected](name="Role_id")
        )
    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

He probado esto y funciona. Cuando elimina el rol, también se eliminan las relaciones (pero no las entidades de permiso) y cuando elimina el permiso, las relaciones con el rol también se eliminan (pero no la instancia del rol). Pero estamos mapeando una relación unidireccional dos veces y ambas entidades son las dueñas de la relación. ¿Podría esto causar algunos problemas para hibernar? ¿Qué tipo de problemas?

¡Gracias!

El código anterior es de otra publicación relacionada.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *