Search code examples
javatransactionspersistenceopenjpa

What is the proper way to clean up an open transaction after PersistenceException?


I'm using OpenJPA 2.0 with a single persistence unit.

In my persistence.xml I have chosen to go with the configuration transaction-type="RESOURCE_LOCAL" and manage transactions manually.

Now, in the code below, if a PersistenceException gets thrown (and caught), how should I clean up the transaction?

    try {
        entityManager.getTransaction().begin();
        MyClassPO myClassPO = (MyClassPO) entityManager
                .createQuery("select bn from myClassPO bn where bn.xxx = :xxx")
                .setParameter("xxx", xxx)
                .getSingleResult();  // NoResultException gets thrown here

        ... do some more stuff ...

        entityManager.getTransaction().commit();

    } catch (PersistenceException e) {

        // what should I do with the open transaction here ??

        logger.error(e);
        throw new MyOtherException(e);
    }

I know that the transaction is not getting cleaned up automatically since the next time I run the same operation I get the error message This operation cannot be performed while a Transaction is active.

Is it as simple as putting entityManager.getTransaction().rollback(); in the catch block?


Solution

  • Yes, with the following notice: according to the documentation, it could throw an IllegalStateException. Also, I suppose you are on the Application Server side, and that's why I would consider the next notice:

    Alternatively you could switch back to JTA, manage on your own the JTA transaction with Bean-Managed-Transaction and use the UserTransaction

    @Resource private UserTransaction userTransaction;