SpringBoot Merge

0

I'm using Spring Full, with Thymeleaf and SpringBoot, but my question is about SpringData, after implementing the interface to make use of the methods Spring makes available in the repository, when I created the Service, I did not find a method that would update .

I have read in some places that .save does the update as well, but in my case, this does not work, it is passed to register a client with id null, so, when registering, generates a new client and does not update , but it generates a new record.

Note: everything else works except the update.

My registration view:

<!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><scriptsrc="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/000000: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('AAA000-S0S');$('.cpf').mask('000.000.000-00',{reverse:true});$('.money').mask('000.000.000.000.000,00',{reverse:true});});</script></body></html>

Myclientlistview:

<!DOCTYPEhtml><htmlxmlns: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>

My 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");
        }

    }

}

My 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);
    }
}
    
asked by anonymous 15.06.2017 / 21:49

1 answer

1

For the save method to do the merge of the object, it needs to know what the id is.

In case of an update, I recommend putting a hidden field containing the id, like this:

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

When executing the request Spring will verify that the id already exists and will merge the data

    
15.06.2017 / 22:00