Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Erro de entrada duplicada ao Inserir um novo Usuario com a mesma Role na tabela usuario_role

Olá

Estou tentando adicionar um novo usuário no system e está apresentando erro de duplicidade na entrada "ROLE_ADMIN" na tabela usuario_role.

A configuração esta a mesma dos vídeos:

@Entity
public class Usuario implements UserDetails {
    private static final long serialVersionUID = 1L;

    @Id
    private String username;

    private String password;
    private String nome;

    @OneToMany(fetch=FetchType.EAGER)
    private List<Role> roles = new ArrayList<Role>();
}

@Entity
public class Role implements GrantedAuthority {
    private static final long serialVersionUID = 1L;

    @Id
    private String role;

private String name;
}

O código gerado pelo Hibernate de criação da tabela é este:

Hibernate: create table Usuario (username varchar(255) not null, nome varchar(255), password varchar(255), primary key (username))
Hibernate: create table Usuario_Role (Usuario_username varchar(255) not null, roles_role varchar(255) not null)
Hibernate: alter table Usuario_Role add constraint UK_9ljdlf4fugq6jh14x7obwpi37 unique (roles_role)
Hibernate: alter table Usuario_Role add constraint FKb32xr1fddmr4pxdxuj5u14f56 foreign key (roles_role) references Role (role)
Hibernate: alter table Usuario_Role add constraint FKm7abqk7krlrd3bb61ecux2fnx foreign key (Usuario_username) references Usuario (username)

Adicionei 3 Roles no banco e no cadastro do usuário elas são exibidas e a pessoa pode selecionar quais as permissões daquele usuário. Quando eu adiciono um usuário e seleciono uma Role que não foi usada, funciona normalmente, porem, quando seleciono uma que já foi usada, da erro de duplicidade. Mesmo se eu tentar inserir o usuário na mão pelo banco da o mesmo erro, então acho que é um problema na criação das tabelas.

Segue o teste feito no banco:

mysql> show tables;
+-----------------+
| Tables_in_kmcdb |
+-----------------+
| atendimento     |
| role            |
| usuario         |
| usuario_role    |
+-----------------+
4 rows in set (0.00 sec)

mysql> select * from role;
+------------+---------------+
| role       | name          |
+------------+---------------+
| ROLE_ADMIN | Administrador |
| ROLE_SUP   | Supervisor    |
| ROLE_TEC   | Técnico      |
+------------+---------------+
3 rows in set (0.00 sec)

mysql> insert into usuario(username, nome, password) value('admin','admin','admin');
Query OK, 1 row affected (0.03 sec)

mysql> insert into usuario(username, nome, password) value('fillipe','fillipe','fillipe');
Query OK, 1 row affected (0.00 sec)

mysql> insert into usuario_role(usuario_username, roles_role) value('admin','ROLE_ADMIN');
Query OK, 1 row affected (0.05 sec)

mysql> insert into usuario_role(usuario_username, roles_role) value('fillipe','ROLE_SUP');
Query OK, 1 row affected (0.00 sec)

mysql> insert into usuario_role(usuario_username, roles_role) value('fillipe','ROLE_TEC');
Query OK, 1 row affected (0.00 sec)

mysql> select * from usuario_role;
+------------------+------------+
| Usuario_username | roles_role |
+------------------+------------+
| admin            | ROLE_ADMIN |
| fillipe          | ROLE_SUP   |
| fillipe          | ROLE_TEC   |
+------------------+------------+
3 rows in set (0.00 sec)

mysql> insert into usuario_role(usuario_username, roles_role) value('fillipe','ROLE_ADMIN');
ERROR 1062 (23000): Duplicate entry 'ROLE_ADMIN' for key 'UK_9ljdlf4fugq6jh14x7obwpi37'
mysql> insert into usuario_role(usuario_username, roles_role) value('admin','ROLE_SUP');
ERROR 1062 (23000): Duplicate entry 'ROLE_SUP' for key 'UK_9ljdlf4fugq6jh14x7obwpi37'

O que preciso modificar para conseguir inserir um novo usuário com a mesma role?

Obrigado

2 respostas

Oi Fillipe,

O problema é que você usou a annotation @OneToMany em vez da @ManyToMany. Minha sugestão é que você destrua o banco e crie de novo. O problema na geração das tabelas está aqui:

alter table Usuario_Role add constraint UK_9ljdlf4fugq6jh14x7obwpi37 unique (roles_role)

Ele tá dizendo que o valor da coluna roles_role não pode ser repetido na tabela. Para ser sincero, não entendi o motivo do hibernate ter gerado essa constraint... Em todo o caso, o ManyToMany faz até um pouco mais de sentido, já que vários usuários podem estar associados com várias roles e vice-versa.

Tem até uma discussão, sem solução, no stackoverflow sobre o assunto. http://stackoverflow.com/questions/4022509/constraint-violation-in-hibernate-unidirectional-onetomany-mapping-with-jointabl

solução!

Oi Alberto..

Alterando para @ManyToMany realmente funcionou, mas fazendo assim a tabela Usuario_role pode ter valores repetidos, certo?

mysql> select * from usuario_role;
+------------------+------------+
| Usuario_username | roles_role |
+------------------+------------+
| admin            | ROLE_ADMIN |
| dani             | ROLE_TEC   |
| Duoli            | ROLE_SUP   |
| admin            | ROLE_ADMIN |
+------------------+------------+
4 rows in set (0.00 sec)

tem como fazer não poder ter valores repetidos? Colocar o @Unique junto com o @ManyToMany funciona nesse caso?

Obrigado