Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

SpringBoot Marge

Pessoal, estou utilizando Spring Full, com Thymeleaf e SpringBoot, mas minha dúvida é sobre o SpringData, após implementar a interface para fazer uso dos métodos que o Spring disponibiliza no repository, ao criar o Service, não encontrei um método que faça o update.

Li em alguns lugares que o .save faz o update também, porem no meu caso, isso não funciona, é passado para o cadastro um cliente com id null, assim, ao cadastrar, gera um novo cliente e não faz o update, mas gera um novo registro.

Obs: todo o resto funciona, menos o update.

Minha view de cadastro:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" />
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Cadastro de Cliente!</title>
        <link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
        <link href="/css/style.css" rel="stylesheet" />
    </head>
<body>

    <header>
        <h1>#PlayTheGame</h1>
    </header>


    <ul>
        <li>
            <a class="active" href="#" style="background-color: #ff3333">Cadastro <span class="glyphicon glyphicon-save" aria-hidden="true" /></a>
        </li>

        <li>    
            <a th:href="@{/Menu}" style="background-color: #8080ff">Menu <span class="glyphicon glyphicon-home" aria-hidden="true" /></a>
        </li>

        <li>
            <a th:href="@{/Cliente/editarCliente}" style="background-color: #6CC150">Editar <span class="glyphicon glyphicon-edit" aria-hidden="true" /></a>
        </li>
    </ul>

    <form th:action="@{/save}"  th:object="${cliente}" method="POST" class="form-horizontal form">
        <div class="div-form">
                <div th:text="${mensagem}" th:if="${not #strings.isEmpty(mensagem)}" class="alert alert-success"/>

                    <div class="form-title">
                        <h1>Cadastro de Cliente</h1>
                    </div>

                    <br />
                    <br />
                    <br />

                    <div class="form-group has-error has-feedback">                    
                        <label for="nome" class="label-form">Nome Completo:*</label> <input type="text" id="nome" th:field="*{nome}" />
                        <label th:if="${#fields.hasErrors('nome')}" th:errors="*{nome}" class="alert alert-danger"/>
                    </div>    

                   <br />
                   <br />

                    <div class="form-group has-error has-feedback">                    
                        <label for="dataNacimento" class="label-form">Data de Nascimento:*</label> <input type="date" id="dataNacimento" th:field="*{dataNacimento}"/>
                        <label th:if="${#fields.hasErrors('dataNacimento')}" th:errors="*{dataNacimento}" class="alert alert-danger"/>
                    </div>        

                    <div>
                        <label th:if="${#fields.hasErrors('sexo')}" th:errors="*{sexo}" class="alert alert-danger"/>
                        <br/>
                        <label> Sexo:*</label>
                    </div>

                    <div>    
                        <label class="radio-inline">
                        <input type="radio" id="masculino" name="sexo" value="Masculino" th:field="*{sexo}"/> Masculino
                        </label> 

                        <label class="radio-inline">
                        <input type="radio" id="feminino" name="sexo" value="Feminino" th:field="*{sexo}"/> Feminino
                        </label> 

                        <label class="radio-inline">
                        <input  type="radio" id="indefinido" name="sexo" value="Indefinido" th:field="*{sexo}"/> Indefinido
                        </label> 
                    </div>        

                   <br />
                   <br />
                    <div class="form-group has-error has-feedback">                    
                        <label for="cpf" class="label-form ">CPF:*</label>
                        <input type="text" id="cpf" th:field="*{cpf}" class="cpf"/>
                        <label th:if="${#fields.hasErrors('cpf')}" th:errors="*{cpf}" class="alert alert-danger"/>
                    </div>        

                   <br />
                   <br />
                    <div class="form-group has-error has-feedback">                    
                        <label for="telefone" class="label-form">Telefone:</label> <input type="text" id="telefone" th:field="*{telefone}" class="phone_with_ddd"/>
                    </div>        

                   <br />
                   <br />
                    <div class="form-group has-error has-feedback">                    
                        <label for="celular" class="label-form">Celular:</label> <input type="text" id="celular" th:field="*{celular}" class="cel_with_ddd"/>
                    </div>        

                   <br />
                   <br />
                    <div class="form-group has-error has-feedback">                    
                        <label for="cep" class="label-form">CEP:*</label> <input type="text" id="cep" th:field="*{cep}" class="cep"/>
                        <label th:if="${#fields.hasErrors('cep')}" th:errors="*{cep}" class="alert alert-danger"/>
                    </div>        

                   <br />
                   <br />
                    <div class="form-group has-error has-feedback">                    
                        <label for="email" class="label-form">Email:*</label> <input type="email" id="email" th:field="*{email}" />
                        <label th:if="${#fields.hasErrors('email')}" th:errors="*{email}" class="alert alert-danger"/>
                    </div>        

                   <!--  <br />
                   <br />
                   <br />
                    <div class="form-group has-error has-feedback">                    
                        <label for="dataNacimento" class="label-form">Data de Nascimento:*</label> <input type="date" id="email" th:field="*{dataNacimento}" />
                        <label th:if="${#fields.hasErrors('dataNacimento')}" th:errors="*{dataNacimento}" class="alert alert-danger"/>
                    </div>     -->    

                   <br />
                   <br />

                    <div>
                        <button type="submit" class="btn btn-primary btn-lg btn-formulario">Cadastrar 
                        <span class="glyphicon glyphicon-save" aria-hidden="true" />
                        </button>
                    </div>
        </div>
    </form>
<script type="text/javascript" src="http://code.jquery.com/jquery-3.0.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.11/jquery.mask.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.mask/1.14.10/jquery.mask.min.js"></script>

<script>    
$(document).ready(function(){
      $('.date').mask('00/00/0000');
      $('.time').mask('00:00:00');
      $('.date_time').mask('00/00/0000 00:00:00');
      $('.cep').mask('00000-000');
      $('.phone').mask('0000-0000');
      $('.phone_with_ddd').mask('(00) 0000-0000');
      $('.cel_with_ddd').mask('(00) 00000-0000');
      $('.phone_us').mask('(000) 000-0000');
      $('.mixed').mask('AAA 000-S0S');
      $('.cpf').mask('000.000.000-00', {reverse: true});
      $('.money').mask('000.000.000.000.000,00', {reverse: true});
    });
</script>
</body>
</html>

Minha view de listagem de clientes:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" />
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Editar Clientes</title>
        <link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
        <link href="/css/style.css" rel="stylesheet" />
    </head>
<body>

    <header>
        <h1>#PlayTheGame</h1>
    </header>


    <ul>
        <li>
            <a th:href="@{/Cliente/cadastroCliente}" style="background-color: #ff3333">Cadastro <span class="glyphicon glyphicon-save" aria-hidden="true" /></a>
        </li>

        <li>    
            <a th:href="@{/Menu}" style="background-color: #8080ff">Menu <span class="glyphicon glyphicon-home" aria-hidden="true" /></a>
        </li>

        <li>
            <a class="active" href="#" style="background-color: #6CC150">Editar <span class="glyphicon glyphicon-edit" aria-hidden="true" /></a>
        </li>
    </ul>

    <div class="panel-body">
            <div class="table-responsive">
                <table class="table table-sm table-striped table-hover table-bordered">
                    <thead>
                        <tr>
                            <th>Nome</th>
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr th:each="cliente : ${clientes}">
                            <td th:text="${cliente.nome}"></td>
                            <td>
                                <div class="btn-group pull-right">
                                    <a class="btn btn-sm btn-primary" th:href="@{/editarCliente/{id}(id=${cliente.id})}" >Editar</a>
                                    <a class="delete btn btn-sm btn-danger" th:href="@{/deletarCliente/{id}(id=${cliente.id})}">Excluir</a>
                               </div>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>

</body>
</html>

minha controller:

package br.com.playTheGame;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import br.com.playTheGame.model.Cliente;
import br.com.playTheGame.service.ClienteService;

@Controller
public class ClienteController {

    @Autowired
    private ClienteService clienteService;

    // igual o findall
    @GetMapping("/Cliente/editarCliente")
    public ModelAndView listarTodos() {
        ModelAndView modelAndView = new ModelAndView("EditarCliente");
        modelAndView.addObject("clientes", clienteService.listarTodos());
        return modelAndView;
    }

    // add
    @GetMapping("/Cliente/cadastroCliente")
    public ModelAndView cadastroCliente(Cliente cliente) {
        ModelAndView modelAndView = new ModelAndView("CadastroCliente");
        modelAndView.addObject("cliente", cliente);
        return modelAndView;
    }

    @GetMapping("/editarCliente/{id}")
    public ModelAndView edit(@PathVariable("id") Long id) {
        return cadastroCliente(clienteService.procurarPorId(id));
    }

    @GetMapping("/deletarCliente/{id}")
    public ModelAndView delete(@PathVariable("id") Long id) {
        clienteService.delete(id);
        return new ModelAndView("redirect:/Cliente/editarCliente");

    }

    @PostMapping("/save")
    public ModelAndView cadastrar(@Valid Cliente cliente, BindingResult result, RedirectAttributes attribute) {
        System.out.println("O id é: "+ cliente.getId());
        if (result.hasErrors()) {
            return this.cadastroCliente(cliente);
        } else {
            if (cliente.getId() == null) {
                attribute.addFlashAttribute("mensagem", "Cliente Cadastrado com sucesso!");
            } else {
                attribute.addFlashAttribute("mensagem", "Edição efetuada com sucesso!");
            }
            clienteService.salvar(cliente);
            return new ModelAndView("redirect:/Cliente/cadastroCliente");
        }

    }

}

minha service:

package br.com.playTheGame.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import br.com.playTheGame.model.Cliente;
import br.com.playTheGame.repository.ClienteRepository;

@Repository
public class ClienteService {

    @Autowired
    private ClienteRepository repository;

    public void salvar(Cliente cliente){
        repository.save(cliente);
    }

    public Iterable<Cliente> listarTodos(){
        return repository.findAll();
    }

    public void delete(Long id){
        repository.delete(id);
    }

    public Cliente procurarPorId(Long id){
        return repository.findOne(id);
    }


}
1 resposta
solução!

Olá Rafael,

Para você atualizar um registro, será necessário o id dele, caso contrário o SpringData não tem como saber qual registro deve ser atualizado, acredito que o mais correto no seu caso, seria ter um campo do tipo hidden que armazena o ID do cliente, quando você enviar os dados para o servidor, você terá o ID e seu update funcionará normalmente. O código seria algo parecido com o abaixo:

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