AmbariJpaLocalTxnInterceptor implements MethodInterceptor { static boolean rollbackIfNecessary(Transactional transactional, Exception e, EntityTransaction txn) { if (txn.getRollbackOnly()) { txn.rollback(); return false; } boolean commit = true; for (Class<? extends Exception> rollBackOn : transactional.rollbackOn()) { if (rollBackOn.isInstance(e)) { commit = false; for (Class<? extends Exception> exceptOn : transactional.ignore()) { if (exceptOn.isInstance(e)) { commit = true; break; } } if (!commit) { txn.rollback(); } break; } } return commit; }  @Override Object invoke(MethodInvocation methodInvocation);  }
@Test public void canBeCommittedIfExceptionsToBeRolledBackOnIsEmpty() { Transactional transactional = createNiceMock(Transactional.class); EntityTransaction transaction = createStrictMock(EntityTransaction.class); expect(transaction.getRollbackOnly()).andReturn(false); expect(transactional.rollbackOn()).andReturn(asArray()); replayAll(); boolean canCommit = rollbackIfNecessary(transactional, new RuntimeException(), transaction); Assert.assertTrue("Should be allowed to commit, since rollbackOn clause is empty", canCommit); verifyAll(); }
@Test public void canBeCommittedIfUnknownExceptionThrown() { Transactional transactional = createNiceMock(Transactional.class); EntityTransaction transaction = createStrictMock(EntityTransaction.class); expect(transaction.getRollbackOnly()).andReturn(false); expect(transactional.rollbackOn()).andReturn(asArray(IllegalArgumentException.class)); replayAll(); boolean canCommit = rollbackIfNecessary(transactional, new RuntimeException(), transaction); Assert.assertTrue("Should be allowed to commit, exception thrown does not match rollbackOn clause", canCommit); verifyAll(); }
@Test public void rolledBackForKnownException() { Transactional transactional = createNiceMock(Transactional.class); EntityTransaction transaction = createStrictMock(EntityTransaction.class); expect(transaction.getRollbackOnly()).andReturn(false); expect(transactional.rollbackOn()).andReturn(asArray(NullPointerException.class, IllegalArgumentException.class)); expect(transactional.ignore()).andReturn(asArray()); transaction.rollback(); replayAll(); boolean canCommit = rollbackIfNecessary(transactional, new IllegalArgumentException("rolling back"), transaction); Assert.assertFalse("Should be rolled back, since exception matches rollbackOn clause", canCommit); verifyAll(); }
@Test public void rolledBackForSubclassOfKnownException() { Transactional transactional = createNiceMock(Transactional.class); EntityTransaction transaction = createStrictMock(EntityTransaction.class); expect(transaction.getRollbackOnly()).andReturn(false); expect(transactional.rollbackOn()).andReturn(asArray(RuntimeException.class)); expect(transactional.ignore()).andReturn(asArray()); transaction.rollback(); replayAll(); boolean canCommit = rollbackIfNecessary(transactional, new IllegalArgumentException("rolling back"), transaction); Assert.assertFalse("Should be rolled back, since exception is subclass of the one in rollbackOn clause", canCommit); verifyAll(); }
@Test public void canBeCommittedIfIgnoredExceptionThrown() { Transactional transactional = createNiceMock(Transactional.class); EntityTransaction transaction = createStrictMock(EntityTransaction.class); expect(transaction.getRollbackOnly()).andReturn(false); expect(transactional.rollbackOn()).andReturn(asArray(IllegalArgumentException.class)); expect(transactional.ignore()).andReturn(asArray(NumberFormatException.class)); replayAll(); boolean canCommit = rollbackIfNecessary(transactional, new NumberFormatException("rolling back"), transaction); Assert.assertTrue("Should be allowed to commit, since ignored exception was thrown", canCommit); verifyAll(); }
@Test public void canBeCommittedIfSubclassOfIgnoredExceptionThrown() { Transactional transactional = createNiceMock(Transactional.class); EntityTransaction transaction = createStrictMock(EntityTransaction.class); expect(transaction.getRollbackOnly()).andReturn(false); expect(transactional.rollbackOn()).andReturn(asArray(Exception.class)); expect(transactional.ignore()).andReturn(asArray(IOException.class)); replayAll(); boolean canCommit = rollbackIfNecessary(transactional, new FileNotFoundException("rolling back"), transaction); Assert.assertTrue("Should be allowed to commit, since subclass of ignored exception was thrown", canCommit); verifyAll(); }
@Test public void rolledBackIfTransactionMarkedRollbackOnly() { Transactional transactional = createNiceMock(Transactional.class); EntityTransaction transaction = createStrictMock(EntityTransaction.class); expect(transaction.getRollbackOnly()).andReturn(true); transaction.rollback(); replayAll(); boolean canCommit = rollbackIfNecessary(transactional, null, transaction); Assert.assertFalse("Should be rolled back, since transaction was marked rollback-only", canCommit); verifyAll(); }