如何在servlet级别捕获OptimisticLockException?

时间:2011-01-28 08:14:32

标签: java jpa toplink-essentials

我正在使用JPA toplink-essential,构建REST Web应用程序。

我有一个servlet,可以找到一个实体并将其删除。

下面的代码我认为我可以在servlet级别捕获乐观的锁异常,但事实并非如此! 而是抛出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 个答案:

答案 0 :(得分:3)

不是100%肯定,但可能是你正在捕获javax.persistence.OptimisticLockException(注意包),但是因为抛出的异常是oracle.toplink.essentials.exceptions.OptimisticLockException,它不会被捕获?即使异类的名称相同,它们也不是同一类。

答案 1 :(得分:2)

我猜它会被em.getTransaction().commit();声明抛出。

因为java doc of RollbackExceptio n如果说:

  

当EntityTransaction.commit()失败时由持久性提供程序抛出。

我强烈相信这不是你真正使用的代码(因为缺少而无法编译)bean.setVersion(Integer.parseInt(12345);},但我“希望”真正的代码有同样的问题

答案 2 :(得分:0)

您是否尝试过调用entityManager.flush();你的try / catch块里面?当JPA刷新时抛出OptimisticLock异常。

此外,您无需以您的方式提交交易。你本来可以做txn.commit();而不是em.getTransaction()。commit();。

我有类似的情况,我能够捕获javax.persistence.OptimisticLockException。在我的例子中,我将ReST端点设为SSB并注入实体管理器。然后我在另一个SSB上调用一个方法,该方法也被注入并充当这个业务逻辑的控制器。此控制器执行flush()并捕获OLEX并重新抛出RestExport和SSB捕获并重试的ApplicationException。使用此模式还需要确保指定TransactionAttributeType.RequiresNew,以便每次重试都会在新事务中进行,因为OLEX会使旧的无效。