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

Mapeamento permite um usuario por role Aula 4. Como deixar varios usuarios por role?

Ola, estou criando um formulario de cadastro de usuarios confome codigo abaixo:

    <h1>Cadastro de usuarios</h1>
<form:form action="${s:mvcUrl('UC#save').build() }" method="post" commandName="usuario" >
     <div class="form-group">
        <label>Nome</label> 
        <form:input path="nome" cssClass="form-control"/>
        <form:errors path="nome" />
    </div>
    <div class="form-group">
        <label>E-Mail</label> 
        <form:input type="email" path="email" cssClass="form-control"/>
        <form:errors path="email" />
    </div>
    <div class="form-group">
        <label>Senha</label>
        <form:input type="password" path="senha" cssClass="form-control"/>
        <form:errors path="senha" /> 
    </div>
    <div class="form-group">
        <form:select path="roles" cssClass="form-control">
            <form:option value="none">---SELECIONE o VALOR----</form:option>
            <form:options items="${roles }" itemValue="authority" itemLabel="authority"/>
        </form:select>
    </div>    
    <div>
        <button type="submit" class="btn btn-primary">Salvar</button>
    </div>        
</form:form>

No meu controller o metodo de salva por enquanto esta dessa forma:

@RequestMapping(method=RequestMethod.POST)
    public ModelAndView save(Usuario usuario,  RedirectAttributes attributes){
        System.out.println(usuario.toString());
        dao.save(usuario);
        attributes.addFlashAttribute("mensagem","usuario salvo com sucesso");
        return new ModelAndView("redirect:usuarios");
    }

E ele funcionou bem para o meu primeiro usuario do tipo "ADMIN" e tambem para o do tipo "USER" o problema é que ao tentar cadastrar mais de um usuario do tipo admin ou do tipo user estou recebendo a seguinte exceção:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'ADMIN' for key 'PRIMARY'
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

Eu ja entendi que o erro se da porque da forma que esta o mapeamento ele esta permitindo apenas um usuario por tipo. Minha duvida é como deve ficar meu mapeamento para que eu possa ter mais de um usuario por role? Atualmente meu mapeamento esta dessa forma:


    @ManyToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
    private List<Role> Roles = new ArrayList<Role>();

No entanto o ManyToMany nao resolveu.

2 respostas
solução!

Oi Michel, poste aqui o código das suas classes Usuario e Role.

Outra coisa, adicione essas informações na anotação @ManyToMany:

@ManyToMany
@JoinTable(name = "usuarios_roles", joinColumns = @JoinColumn(name = "usuario_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
private List<Role> roles = new ArrayList<Role>();

Código classe Role

@Entity
public class Role implements GrantedAuthority{


    private static final long serialVersionUID = 1L;


    @Id
    private String     authority;

    public Role() {
    }


    public Role(String authority) {
        this.authority = authority;
    }
    @Override
    public String getAuthority() {
        return authority;
    }
    public void setAuthority(String authority) {
        this.authority = authority;
    }



}

Código classe Usuario antes da correção a cima

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

@Entity
public class Usuario implements UserDetails
{

    private static final long serialVersionUID = 1L;

    @Id    
    private String email;

    private String senha;

    private String nome;

    @ManyToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
    private List<Role> Roles = new ArrayList<Role>();



     public Usuario() {
    }


    @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return this.Roles;
        }


    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getSenha() {
        return senha;
    }

    public void setSenha(String senha) {
        this.senha = senha;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public List<Role> getRoles() {
        return Roles;
    }

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

    public void addRole(Role role){
        Roles.add(role);
    }

    @Override
    public String getPassword() {
        return senha;
    }

    @Override
    public String getUsername() {
        return nome;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }


    @Override
    public String toString() {
        return "Usuario [email=" + email + ", senha=" + senha + ", nome=" + nome + ", Roles=" + Roles + "]";
    }




}

Vou testar a solução acima

O erro persistiu

 Duplicate entry 'ROLE_ADMIN' for key 'PRIMARY'