3
respostas

Alterar dados dos usuários não funciona, está duplicando dados

Implementei o spring security no meu projeto, já consigo registrar novos usuários e fazer login/logout. Agora estou tentando fazer a edição dos dados desse usuário, porém quando eu salvo, ele duplica os dados e retorna o erro:

javax.persistence.NonUniqueResultException: query did not return a unique result: 2

Segue código:

ServicoUsuario:

@Service
public class ServiceUsuario {

    @Autowired
    private RepositoryUsuario repUsuario;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    public Usuario encontrarPorUsername(String Username) {
        return repUsuario.findByUsername(Username);
    }

    public void salvar(Usuario usuario) {
        usuario.setSenha(passwordEncoder.encode(usuario.getSenha()));
        repUsuario.save(usuario);
    }

    public Usuario getOne(Long id) {
        return repUsuario.getOne(id);
    }

Usuário controller:

@Controller
@RequestMapping("/usuario")
public class UsuarioController {

    @Autowired
    private ServiceUsuario serviceUsuario;

    @Autowired
    private RepositoryUsuario repUsuario;

    @GetMapping("/minhaConta")
    public ModelAndView minhaConta(HttpServletRequest request) {
        ModelAndView mv = new ModelAndView("usuario/minhaConta");
        String username = request.getUserPrincipal().getName();
        Usuario usuario = serviceUsuario.encontrarPorUsername(username);
        mv.addObject("usuario", usuario);
        return mv;
    }

    @GetMapping("/alterar/{id}")
    public String alterar(@PathVariable("id") Long id, Model model) {
        Usuario usuario = serviceUsuario.getOne(id);
        model.addAttribute("usuario", usuario);
        return "usuario/editarConta";
    }

    @PostMapping("/alterar")
    public ModelAndView alterar(@Valid Usuario usuario, BindingResult result) {
        ModelAndView mv = new ModelAndView();
        if (result.hasErrors()) {
            System.out.println(result.getAllErrors());
            mv.setViewName("usuario/editarConta");
            mv.addObject(usuario);
        } else {
            mv.setViewName("redirect:/usuario/minhaConta");
            repUsuario.save(usuario);
        }

        return mv;
    }

Formulário de edição:

<h1 class="tituloRegist">Editar dados da conta:</h1>

            <div class="divRegist">

                <form class="form-horizontal formRegist" action="/usuario/alterar" method="POST" th:object="${usuario}">
                    <input type="hidden" th:field="*{id}">
                    <div class="form-group">
                        <label for="inputNome">Nome</label>
                        <input type="text" class="form-control" id="inputNome" placeholder="Nome" th:field="*{nome}">
                        <label th:if="${#fields.hasErrors('nome')}" th:errors="*{nome}" class="validation-message"></label>
                    </div>

                    <div class="form-group">
                        <label for="inputSobrenome">Sobrenome</label>
                        <input type="text" class="form-control" id="inputSobrenome" placeholder="Sobrenome"  th:field="*{sobrenome}">
                        <label th:if="${#fields.hasErrors('sobrenome')}" th:errors="*{sobrenome}" class="validation-message"></label>
                    </div>

                    <div class="form-group">
                        <label for="inputEmail">Email</label>
                        <input type="text" class="form-control" id="inputEmail" placeholder="Email"  th:field="*{email}">
                        <label th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="validation-message"></label>
                    </div>
                    <input type="hidden" th:field="*{senha}">
                    <input type="hidden" th:field="*{username}">
                    <button type="submit" class="btn btn-primary">Salvar</button>

                </form>
            </div>
3 respostas

Olá Guilherme!

Quando você executa essa linha:

alterar(@Valid Usuario usuario ...

O ID do usuário está sendo passado dentro desse objeto? Porque quando você executa o método save e não passa o ID será criado um novo. Se for passado o ID ele verá que já existe aquele objeto no banco e irá atualizar.

Olá!

Sim, logo abaixo a tag form, eu passo o id através de um input hidden, conforme abaixo:

<input type="hidden" th:field="*{id}">

Olá Guilherme, tenta fazer assim:

<input hidden type="number" th:field="*{id}">

Veja se funciona pra ti!