1
resposta

Problema de exception com Transação no Controller

Boa noite,

Estava tentando fazer com que quando ocorresse um OptimisticLockException fosse possível recuperar o produto mais atualizado possível e retorná-lo a tela com uma mensagem. Porém toda vez que saia do método salvar do ProdutoController tomava o erro TransactionSystemException: Could not commit JPA transaction;

Consegui resolver o problema colocando a transação em um service e chamando no Controller. Existe alguma outra solução?

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

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

        try {
            // Se tirar o transação do Controller e chamar o método do service funciona mesmo com a exceção OptimisticLockException
            //produtoService.salvar(produto);
            // Chamando o DAO assim dá  TransactionSystemException: Could not commit JPA transaction
            produtoDao.salvar(produto);

        }catch (OptimisticLockException e) {
            model.addAttribute("produto", produtoDao.getProduto(produto.getId()));
            model.addAttribute("message", "O Produto " + produto.getNome() + " foi alterado por outro usuário ao mesmo tempo. Por favor, reedite-o novamente.");

            return form(produto);
        }

        return "redirect:/";
    }

package br.com.caelum.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import br.com.caelum.dao.ProdutoDao;
import br.com.caelum.model.Produto;

@Service
public class ProdutoService {
    @Autowired
    private ProdutoDao produtoDao;

    @Transactional
    public void salvar(Produto produto) {
        produtoDao.salvar(produto);
    }
}
1 resposta

Felipe, tudo bem ?

Imagino que como seja o Spring que esteja gerenciando o seu banco de dados, ele precisa saber quando é necessário abrir ou não uma transação.

Você até pode fazer na mão, mas ai você perde totalmente a vantagem em deixar o spring fazer.