Testing Active Objects : java.lang.IllegalStateException: There are two concurrently open transactions!

Hi Everyone,
I am trying to test active object accessor methods. I am getting an error

“java.lang.IllegalStateException: There are two concurrently open transactions!”

I am pretty sure that all the written tests are concurrent and I think the test runner class while trying to reset the database is doing something which is causing this error to occur. Because I am getting this error after the test case has run.

This is my DatabaseUpdater class ->

    public void createEntry()throws Exception{
        final AModel entry = aAccessor.createEntry(model);

    public static class AAccessorImplTestDatabaseUpdater implements DatabaseUpdater {

        public void update(EntityManager em) throws Exception {
            ao = new TestActiveObjects(em);
            ao.executeInTransaction(() -> {
                final A a = ao.create(A.class);
                return a;

and this the method I am testing

    public AModel createEntry(AModel model) throws NullArgumentException {
        if (!validateEntry(model)) {
            return null;
        final AModel aModel = ao.executeInTransaction(() -> {
            final A m = ao.create(A.class);
            return model;
        ao.flushAll(); //added to because of error
        return aModel;

First solution:

  • Annotate the test method with @net.java.ao.test.jdbc.NonTransactional.
  • Unfortunately, this means AO creates-and-drops the schema for each unit test instead of reverting the transaction (and it takes 12s to create-and-drop with Oracle and a few tables). Given a few hundred tests in a project, it’s easily 40 minutes of overhead in a build.

Second solution:

  • Override/replace TestActiveObjects with a custom implementation.
  • Why? Because it started a nested transaction, despite ActiveObjectsMethodRule already doing it,
  • The nested transactions made JDBC complain. We’ve replaced TestActiveObjects’ transaction with a no-op.

Here is the result:

 * Copy of {@link com.atlassian.activeobjects.test.TestActiveObjects} in version com.atlassian.activeobjects:activeobjects-test:3.2.10,
 * the only difference is we don't wrap the transactions in one another, because:
 * - ActiveObjectsJUnitRunner already uses ActiveObjectsTransactionMethodRule which starts the transaction in the 'before()';
 * - If we do it, ActiveObjectsTransactionMethodRule will throw an exception while performing the rollback, saying there
 *   are two transactions open.
public class CustomTestActiveObjects extends EntityManagedActiveObjects {
    private static final Map<String, DatabaseType> DATABASE_PRODUCT_TO_TYPE_MAP = ImmutableMap.<String, DatabaseType>builder()
                .put("H2", DatabaseType.H2)
                .put("HSQL Database Engine", DatabaseType.HSQL)
                .put("MySQL", DatabaseType.MYSQL)
                .put("PostgreSQL", DatabaseType.POSTGRESQL)
                .put("Oracle", DatabaseType.ORACLE)
                .put("Microsoft SQL Server", DatabaseType.MS_SQL)
                .put("DB2", DatabaseType.DB2)

    public CustomTestActiveObjects(final EntityManager entityManager) {
        super(entityManager, TransactionCallback::doInTransaction, findDatabaseType(entityManager));

    private static DatabaseType findDatabaseType(EntityManager entityManager) {
        try (Connection connection = entityManager.getProvider().getConnection()) {
            String dbName = connection.getMetaData().getDatabaseProductName();
            for (Entry<String, DatabaseType> entry : DATABASE_PRODUCT_TO_TYPE_MAP.entrySet()) {
                if (dbName.startsWith(entry.getKey()))
                    return entry.getValue();
            return DatabaseType.UNKNOWN;
        } catch (SQLException sqle) {
            throw new ActiveObjectsException(sqle);