简体   繁体   English

如何在servlet级别捕获OptimisticLockException?

[英]How to catch OptimisticLockException in servlet level?

I'm using JPA toplink-essential, building REST web app. 我正在使用JPA toplink-essential,构建REST Web应用程序。

I have a servlet that find one entity and delete it. 我有一个servlet,找到一个实体并删除它。

Below code I thought I could catch optimistic lock exception in servlet level but its not! 下面的代码我认为我可以在servlet级别捕获乐观的锁异常,但事实并非如此! Instead RollbackException is thrown, and that's what documentation says: 而是抛出RollbackException,这就是文档所说的:

But then when I see the Netbean IDE GlassFish log, somewhere, optimisticLockException is thrown. 但是当我在某处看到Netbean IDE GlassFish日志时,抛出了optimisticLockException。 It's just not being caught in my code. 它只是没有陷入我的代码中。 (my system print message doesn't get displayed so I'm sure its not going in there.) (我的系统打印消息没有显示,所以我确定它不会进入那里。)

I tried to import each packages (one at a time of course) and tested with catch clause but both time, it is not going into the catch block even though log error says "optimistic exception". 我试图导入每个包(当然一次一个)并使用catch子句进行测试,但两次都是,即使日志错误显示“乐观异常”,也不会进入catch块。

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

So where the OptimisticLockException is thrown????? 那么抛出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();
            }
        }

Error msg: 错误消息:

[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

Not 100% sure, but could it be that you're catching javax.persistence.OptimisticLockException (notice the package), but as the thrown exception is oracle.toplink.essentials.exceptions.OptimisticLockException, it's not getting caught? 不是100%肯定,但可能是你正在捕获javax.persistence.OptimisticLockException(注意包),但是因为抛出的异常是oracle.toplink.essentials.exceptions.OptimisticLockException,它不会被捕获? Even though the name of exception-class is the same, they're not the same class. 即使异类的名称相同,它们也不是同一个类。

I would guess that it is thrown in the em.getTransaction().commit(); 我猜它会被em.getTransaction().commit(); statement. 声明。

Because the java doc of RollbackExceptio n if said: 因为RollbackExceptiojava文件如果说:

Thrown by the persistence provider when EntityTransaction.commit() fails. 当EntityTransaction.commit()失败时由持久性提供程序抛出。

I strongly belive that this is not the code you realy use (it would not compile because of a missing ) in line bean.setVersion(Integer.parseInt(12345); ), but i "hope" that the real code has the same problem. 我强烈相信这不是你真正使用的代码(它不会因为缺失而编译)在bean.setVersion(Integer.parseInt(12345); )中,但我“希望”真正的代码有同样的问题。

Have you tried calling entityManager.flush(); 你试过调用entityManager.flush(); inside your try/catch block? 你的try / catch块里面? When JPA flushes is when the OptimisticLock exception is thrown. 当JPA刷新时抛出OptimisticLock异常。

Also you need not commit the transaction in the manner you did. 您也不需要以您的方式提交事务。 You simply could have done txn.commit(); 你本来可以做txn.commit(); instead of em.getTransaction().commit();. 而不是em.getTransaction()。commit();.

I have a similar situation where I am able to catch javax.persistence.OptimisticLockException. 我有类似的情况,我能够捕获javax.persistence.OptimisticLockException。 In my case I made the ReST endpoint a SSB and inject the entity manager. 在我的例子中,我将ReST端点设为SSB并注入实体管理器。 I then call a method on another SSB which is also injected and acts as a controller for this piece of biz logic. 然后我在另一个SSB上调用一个方法,该方法也被注入并充当这个业务逻辑的控制器。 This controller performs a flush() and catches the OLEX and rethrows and ApplicationException which the Rest endpoint / SSB catches and retries. 此控制器执行flush()并捕获OLEX并重新抛出RestExport和SSB捕获并重试的ApplicationException。 Using this pattern you also need to make sure to specify TransactionAttributeType.RequiresNew so that each retry you make occurs in a fresh transaction since the OLEX invalidates the old one. 使用此模式还需要确保指定TransactionAttributeType.RequiresNew,以便每次重试都会在新事务中进行,因为OLEX会使旧的无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM