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

Tipo de tratamento em caso de OptimisticLockException

Boa noite,

Só fiquei na dúvida sobre qual a melhor abordagem em caso de OptimisticLockException seguir. Devo recuperar o último produto do banco fazer o merge e salvar ou é melhor devolver os dados mais atualizados para a tela com uma mensagem e deixar o usuário fazer o merge?

No caso do código fiz um teste que ficou assim

package br.com.caelum.dao;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.LockModeType;
import javax.persistence.OptimisticLockException;
import javax.persistence.RollbackException;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import br.com.caelum.JpaConfigurator;
import br.com.caelum.model.Produto;

public class TesteLockOtimista {

    public static void main(String[] args) {
        EntityTransaction t1 = null;
        EntityTransaction t2 = null;

        try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JpaConfigurator.class)) {

            EntityManagerFactory factory = context.getBean(EntityManagerFactory.class);

            EntityManager em1 = factory.createEntityManager();
            EntityManager em2 = factory.createEntityManager();

            t1 = em1.getTransaction();
            t2 = em2.getTransaction();

            t1.begin();
            t2.begin();


            try {
                Produto produtoDoEM1 = em1.find(Produto.class, 1, LockModeType.OPTIMISTIC);
                produtoDoEM1.setNome("Joao");

                Produto produtoDoEM2 = em2.find(Produto.class, 1, LockModeType.OPTIMISTIC);
                produtoDoEM2.setPreco(500);

                t1.commit();
                t2.commit();

            }catch (RollbackException e) {

                if(e.getCause() instanceof OptimisticLockException) {
                    em2.close();
                    EntityManager em3 = factory.createEntityManager();        
                    em3.getTransaction().begin();
                    Produto produtoDoEM3 = em3.find(Produto.class, 1, LockModeType.OPTIMISTIC);
                    // Aqui fazendo o merge da informação
                    produtoDoEM3.setPreco(500);
                    em3.getTransaction().commit();
                }else {
                    System.out.println(e);
                }
            }

        }catch (Exception e) {
            t2.rollback();
            System.out.println(e);
        }
    }
}
1 resposta
solução!

Oi Felipe, perdão pela demora. Acho que nesse tipo de caso, pensando numa aplicação mesmo, o melhor é tentar achar a solução mais simples. Eu simplesmente levaria o usuário para a mesma página com uma mensagem indicando que ele deveria recarregar o formulário. Inclusive explicaria o motivo... Seu código ficaria mais simples e o usuário ficaria informado.