What is the best way to edit an entity with Spring?

Asked

Viewed 170 times

1

In my Controller I have the following mapping to display a person’s registration edit form:

@GetMapping("/mostraEmpresaEdicao/{idpessoa}")
    public ModelAndView mostraEmpresaEdicao(@PathVariable("idpessoa") Long idpessoa) {
        
        Optional<Pessoa> pessoa = pessoaRepository.findById(idpessoa);
        ModelAndView modelAndView = new ModelAndView("cadastro/editarpessoa");
        modelAndView.addObject("pessoaobj", pessoa.get());
        return modelAndView;
    }

The person is loaded into the editarpessoa.html form. What is the best way to edit this person? Assuming it is possible to edit all the fields of a person. I can put the action of this form to my save method, which I also use to save a new registration?

    @RequestMapping(method=RequestMethod.POST, value="/salvarpessoa")
    public ModelAndView salvar(Pessoa pessoa) {
        pessoaRepository.save(pessoa);
        return pessoas();
    }

NOTE: The person() is a method to list the registrations.

editarpessoa.html with the action for /salvarpessoa, also used in new entries:

    <form action="#" 
          th:action="@{/salvarpessoa}"
          th:object="${pessoaobj}" 
          method="post">
         <label>Id</label>
         <input name="id" readonly="readonly" th:field="*{id}">
         <label>Nome</label>
         <input name="nome" th:field="*{nome}">
         <label>Sobrenome</label>
         <input name="sobrenome" th:field="*{sobrenome}">   
    
         <button class="btn waves-effect waves-light" type="submit" name="salvar">Salvar
              <i class="material-icons right">send</i>
         </button>
         
    </form>

Or the most correct is to create a proper mapping to edit it by changing the form action for it?

    @PostMapping("/editarpessoa/{idpessoa}")
    public String editar(Pessoa pessoaedicao) {
        
        Optional<Pessoa> pessoa = pessoaRepository.findById(pessoaedicao.getId());
        pessoa.get().setNome(pessoaedicao.getNome());
        pessoa.get().setSobrenome(pessoaedicao.getSobrenome());
        pessoaRepository.save(pessoa.get());
            
        return "cadastro/cadastropessoa";
    }

If creating a separate method is ideal, is it correct to use set() to change the entity fields and then save(), or is it okay to just use save()? In the background, Spring Data will see that the ID already exists and will give the update?

    @PostMapping("/editarpessoa/{idpessoa}")
    public String editar(@PathVariable("idpessoa") Long idpessoa, Pessoa pessoaedicao) {
        
        Optional<Pessoa> pessoa = pessoaRepository.findById(idpessoa);
        pessoaRepository.save(pessoa.get());
            
        return "cadastro/cadastropessoa";
    }

By checking the manual, the save method does persist if the entity is new, and merge if it already exists:

@Transactional
public <S extends T> S save(S entity) {
    if (this.entityInformation.isNew(entity)) {
        this.em.persist(entity);
        return entity;
    } else {
        return this.em.merge(entity);
     }
 }

So I believe that if the data I’m going to edit is the same as a new registration, I don’t use some kind of form just with some of this data, either set the data first and then save the entity, or just use save().

  • Thank you Statelessdev. Just one more question: In the editing method that I will create separately is correct the way I did? I load from the bench, set and then use save: Optional<Pessoa> pessoa = pessoaRepository.findById(pessoaedicao.getId()); &#xA;pessoa.get().setNome(pessoaedicao.getNome()); &#xA;pessoa.get().setSobrenome(pessoaedicao.getSobrenome()); &#xA;pessoaRepository.save(pessoa.get()); As I said, just using save() works. Is there the right one? Load, set and save, or just save as below? pessoaRepository.save(pessoaedicao);

  • 1

    If your object already arrives with the changes, just save. It makes no sense to spend system resource to go to database and recover data you already have at hand. Your idea is to optimize whenever possible. To tell you the truth, your system is so simple that you could use the same endpoint to create a new person or edit. The point is that in the real world, in general, you will need two endpoints, since normally you will apply business rules before you effectively save in the bank.

  • Perfect. Thank you very much.

1 answer

1


Jpa Repository already updates dynamically if the id of the entity you are sending exists, a trivial and well used form in the market is validation if the record already exists in the database to avoid using Put as "post" allowing its creation, would look something like this

            User userupdate = userRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("o id não foi encontrado na base"));

In the case of the password is a particularity that I think is an additional validation attention to "avoid" traffic your password for more than encrypted would be something to think.

The Exception placed in the code is a customization to indicate the upper layer that the resource was not found avoiding this dual endpoint update function perform both update and creation

Browser other questions tagged

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