Как отловить OptimisticLockException на уровне сервлета?

Я использую JPA toplink-essential, создавая веб-приложение REST.

У меня есть сервлет, который находит одну сущность и удаляет ее.

Ниже кода я думал, что могу поймать оптимистичное исключение блокировки на уровне сервлета, но это не так! Вместо этого выбрасывается RollbackException, о чем говорится в документации:

Но затем, когда я вижу журнал Netbean IDE GlassFish, где-то возникает исключение optimisticLockException. Это просто не попадает в мой код. (мое системное сообщение печати не отображается, поэтому я уверен, что его там не будет.)

Я попытался импортировать каждый пакет (по одному, конечно) и протестировал с предложением catch, но оба раза он не попадает в блок catch, хотя в журнале ошибки написано «оптимистичное исключение».

import javax.persistence.OptimisticLockException;
import oracle.toplink.essentials.exceptions.OptimisticLockException;

Итак, где возникает исключение OptimisticLockException ?????

@Path("delete")
@DELETE
@Consumes("application/json")
public Object planDelete(String content) {

   try {
            EntityManager em = EmProvider.getInstance().getEntityManagerFactory().createEntityManager();

            EntityTransaction txn = em.getTransaction();
            txn.begin();
            jObj = new JSONObject(content);
            MyBeany bean = em.find(123);

            bean.setVersion(Integer.parseInt(12345));
            em.remove(bean);


            //here commit!!!!!
            em.getTransaction().commit(); 
        }
        catch(OptimisticLockException e) {  //this is not caught here :(
            System.out.pritnln("here");
            //EntityTransactionManager.rollback(txn);
            return HttpStatusHandler.sendConflict();
        }
        catch(RollbackException e) {
            return HttpStatusHandler.sendConflict();
        }
        catch(Exception e) {
            return HttpStatusHandler.sendServerError(e);
        }
        finally {
            if(em != null) {
                em.close();
            }
        }

Сообщение об ошибке:

[TopLink Warning]: 2011.01.28 05:11:24.007--UnitOfWork(22566987)
--Exception [TOPLINK-5006] 
(Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): 
oracle.toplink.essentials.exceptions.OptimisticLockException

    [TopLink Warning]: 2011.02.01 08:50:15.095--UnitOfWork(681660)--
javax.persistence.OptimisticLockException: Exception [TOPLINK-5006] (Oracle TopLink 
Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): 
oracle.toplink.essentials.exceptions.OptimisticLockException

person Meow    schedule 28.01.2011    source источник


Ответы (3)


Не уверен на 100%, но может быть, вы поймали исключение javax.persistence.OptimisticLockException (обратите внимание на пакет), но поскольку выброшенное исключение - oracle.toplink.essentials.exceptions.OptimisticLockException, его не поймают? Несмотря на то, что имя класса исключения то же самое, это не один и тот же класс.

person esaj    schedule 28.01.2011
comment
Хорошая точка зрения. Я поймал javax.persistence.OptimisticLockException в приведенном выше коде. Я изменил свое предложение catch, чтобы поймать oracle.toplink.essentials.exceptions.OptimisticLockException, но это пока не улавливается. Я добавил сообщение об ошибке в свой пост. он показывает оба типа пакетов .. очень сбивает с толку - person Meow; 01.02.2011
comment
Итак, я предполагаю, как указал Ральф, исключение выбрасывается внутри em.getTransaction (). Commit, поэтому я не могу вручную поймать optimisticLockException. Единственный способ - поймать исключение отката и предположить, что произошел конфликт ??? :( - person Meow; 01.02.2011
comment
Этот улов (Exception e) должен улавливать любое исключение (не отмеченное или отмеченное), возникшее в блоке try. Вероятно, вам следует получить трассировку стека из этого исключения и / или поставить точку останова в строке фиксации и выполнить код, чтобы увидеть, что произойдет. - person esaj; 01.02.2011
comment
Похоже, что в моем случае он не улавливается после исследований и нескольких тестов. Хотя один из способов отличить - это бросить RollbackException, e.getCause (), а затем посмотреть, является ли это исключение optimisticLockException. В моем случае этого было бы достаточно :) - person Meow; 02.02.2011

Я бы предположил, что это добавлено в оператор em.getTransaction().commit();.

Поскольку java doc RollbackExceptio n, если сказано:

Выдается поставщиком сохраняемости при сбое EntityTransaction.commit ().

Я твердо верю, что это не тот код, который вы действительно используете (он не будет компилироваться из-за отсутствия) в строке bean.setVersion(Integer.parseInt(12345);), но я «надеюсь», что реальный код имеет ту же проблему.

person Ralph    schedule 28.01.2011
comment
Я исправил эту опечатку, но проблема по-прежнему в том, что оба оптимистичных пакета блокировки не обнаруживаются. - person Meow; 01.02.2011

Вы пробовали вызвать entityManager.flush (); внутри вашего блока try / catch? Когда JPA сбрасывается, возникает исключение OptimisticLock.

Также вам не нужно фиксировать транзакцию так, как вы это сделали. Вы просто могли бы сделать txn.commit (); вместо em.getTransaction (). commit () ;.

У меня аналогичная ситуация, когда я могу поймать javax.persistence.OptimisticLockException. В моем случае я сделал конечную точку ReST SSB и внедрил диспетчер сущностей. Затем я вызываю метод на другом SSB, который также вводится и действует как контроллер для этой части бизнес-логики. Этот контроллер выполняет flush () и перехватывает OLEX, а также повторно генерирует исключение ApplicationException, которое конечная точка Rest / SSB перехватывает и пытается повторить. Используя этот шаблон, вам также необходимо указать TransactionAttributeType.RequiresNew, чтобы каждая повторная попытка выполнялась в новой транзакции, поскольку OLEX аннулирует старую.

person NBW    schedule 22.08.2011