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

Duplicando o registro no merge

Quando eu tento efetuar a atualização do registro ele automaticamente faz um novo registro com os mesmos dados. Quando o método merge() é invocado o Hibernate faz um select na tabela Loja e depois faz o insert do produto

14:21:54,477 INFO  [stdout] (default task-4) Hibernate: select loja0_.id as id1_1_0_, loja0_.nome as nome2_1_0_ from Loja loja0_ where loja0_.id=?
14:21:54,481 INFO  [stdout] (default task-4) Hibernate: insert into Produto (descricao, linkDaFoto, loja_id, nome, preco, versao) values (?, ?, ?, ?, ?, ?)
14:21:54,484 INFO  [stdout] (default task-4) Hibernate: select categoria0_.id as id1_0_0_, categoria0_.nome as nome2_0_0_ from Categoria categoria0_ where categoria0_.id=?
14:21:54,485 INFO  [stdout] (default task-4) Hibernate: select categoria0_.id as id1_0_0_, categoria0_.nome as nome2_0_0_ from Categoria categoria0_ where categoria0_.id=?
14:21:54,488 INFO  [stdout] (default task-4) Hibernate: insert into Produto_Categoria (Produto_id, categorias_id) values (?, ?)
14:21:54,490 INFO  [stdout] (default task-4) Hibernate: insert into Produto_Categoria (Produto_id, categorias_id) values (?, ?)

Nesse caso, o Hibernate não deveria faz um select na tabela Produto e depois o update? Eu até fiz o download do código da aula, porém esse problema persisti, ou seja, o Hibernate não faz um update apenas um insert, duplicando o produto.

Esse é o método do ProdutoDAO.

    public void insere(Produto produto) {
        if (produto.getId() == null)
            em.persist(produto);
        else
            em.merge(produto);
    }

Esse é o modelo Produto

public class Produto {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @NotEmpty
    private String nome;

    @NotEmpty
    private String linkDaFoto;

    @NotEmpty
    @Column(columnDefinition = "TEXT")
    private String descricao;

    @Min(20)
    private double preco;

    @ManyToMany
    private List<Categoria> categorias = new ArrayList<>();

    @Valid
    @ManyToOne
    private Loja loja;

    @Version
    private Integer versao;

    //métodos get e set omitidos...
}

E esse é o controller

    @Transactional
    @RequestMapping(method=RequestMethod.POST, name="cadastraProduto")
    public String salvar(@ModelAttribute @Valid Produto produto, BindingResult result, RedirectAttributes atts) {

        if(result.hasErrors()) {
            return form(produto);
        }

        produtoDao.insere(produto);

        return "redirect:/";
    }
1 resposta
solução!

Não tinha inserido a propriedade versão na view. Agora foi certinho. Foi mal...