Как отловить 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
3 ответа
Не уверен на 100%, но может ли быть так, что вы ловите javax.persistence.OptimisticLockException (обратите внимание на пакет), но, поскольку выбрасываемое исключение - oracle.toplink.essentials.exceptions.OptimisticLockException, оно не будет поймано? Несмотря на то, что имя класса исключений совпадает, они не совпадают.
Я предполагаю, что это брошено в em.getTransaction().commit();
заявление.
Потому что документ Java от RollbackExceptio n, если сказал:
Брошенный провайдером постоянства, когда EntityTransaction.commit() терпит неудачу.
Я твердо верю, что это не тот код, который вы действительно используете (он не будет компилироваться из-за отсутствия) в строке bean.setVersion(Integer.parseInt(12345);
), но я "надеюсь", что реальный код имеет ту же проблему.
Вы пытались вызвать 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 лишает законной силы старую транзакцию.