3

我正在使用 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
4

3 回答 3

3

不是 100% 确定,但可能是您正在捕获 javax.persistence.OptimisticLockException(注意包),但是由于抛出的异常是 oracle.toplink.essentials.exceptions.OptimisticLockException,它没有被捕获吗?即使异常类的名称相同,它们也不是同一个类。

于 2011-01-28T18:16:12.533 回答
2

我猜它是在 em.getTransaction().commit();声明中抛出的。

因为RollbackException n 的 java doc if 说:

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

我坚信这不是您真正使用的代码(由于缺少 行而无法编译bean.setVersion(Integer.parseInt(12345);),但我“希望”真正的代码有同样的问题。

于 2011-01-28T08:39:59.350 回答
1

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

此外,您不需要以您所做的方式提交事务。你可以简单地完成 txn.commit(); 而不是 em.getTransaction().commit();。

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

于 2011-08-22T17:44:44.123 回答