Springboot Merge

Asked

Viewed 175 times

0

I am using Spring Full, with Thymeleaf and Springboot, but my question is about Springdata, after implementing the interface to make use of the methods that Spring provides in Restpository, when creating Service, I could not find a method to update.

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

Note: everything else works except the update.


My view of registration:

<!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>

My Customer Listing View:

<!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>

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

1 answer

1


For the save method to do the merge of the object, he needs to know which is the id.

In the case of an update, I recommend placing an Hidden field containing the id, thus:

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

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.