greenrobot/greenDAO · error · DaoException

Callable failed

Error message

Callable failed

What it means

callInTxNoException wraps any Exception thrown by the user-supplied Callable inside a DaoException with message "Callable failed" while the database transaction is still open (it is then rolled back by the finally/endTransaction). The original exception is the cause. This lets greendao normalize arbitrary callable failures into its own exception type.

Solutions

  1. Read getCause() of the DaoException to find the real exception thrown inside the callable and fix that root problem.
  2. Make the callable null-safe: validate entity objects, field values, and any external inputs before calling them.
  3. Move expensive validation before the transaction so only fail-safe DB writes remain inside the callable.
  4. If you need to handle failures yourself, catch DaoException around callInTxNoException instead of throwing inside the callable.

Example fix

// before
daos.callInTxNoException(() -> {
    order.setCustomer(customer.getId()); // NPE if customer is null
    return orderDao.insert(order);
});
// after
if (customer == null) throw new IllegalArgumentException("customer required");
daos.callInTxNoException(() -> {
    order.setCustomer(customer.getId());
    return orderDao.insert(order);
});
Defensive patterns

Strategy: try-catch

Validate before calling

if (order == null || customer == null) {
    throw new IllegalArgumentException("order and customer must be non-null before tx");
}

Try / catch

try {
    result = daoSession.callInTxNoException(myCallable);
} catch (DaoException e) {
    Throwable cause = e.getCause(); // real failure inside the callable
    log.severe("tx callable failed: " + cause);
}

Prevention

When it happens

Trigger: Any Exception thrown from the Callable passed to daoSession.callInTxNoException(callable): null pointer inside the callable, DAO insert/update failures wrapped as RuntimeException, or application-level validation exceptions thrown deliberately by the callable.

Common situations: Developers do bulk inserts/updates in a transaction and one entity violates a constraint or NPEs; the wrapped DaoException surfaces after the transaction is rolled back, often confusing them because the root cause is nested.

Related errors


AI-assisted analysis of greenrobot/greenDAO@0bbb338e17 (2026-09-08). Data as JSON: /api/errors/4740f80a50c5d29a. Report an issue: GitHub.

Appendix: source

Thrown at DaoCore/src/main/java/org/greenrobot/greendao/AbstractDaoSession.java:185

            db.setTransactionSuccessful();
            return result;
        } finally {
            db.endTransaction();
        }
    }

    /**
     * Like {@link #callInTx(Callable)} but does not require Exception handling (rethrows an Exception as a runtime
     * DaoException).
     */
    public <V> V callInTxNoException(Callable<V> callable) {
        db.beginTransaction();
        try {
            V result;
            try {
                result = callable.call();
            } catch (Exception e) {
                throw new DaoException("Callable failed", e);
            }
            db.setTransactionSuccessful();
            return result;
        } finally {
            db.endTransaction();
        }
    }

    /** Gets the Database for custom database access. Not needed for greenDAO entities. */
    public Database getDatabase() {
        return db;
    }

    /** Allows to inspect the meta model using DAOs (e.g. querying table names or properties). */
    public Collection<AbstractDao<?, ?>> getAllDaos() {
        return Collections.unmodifiableCollection(entityToDao.values());
    }

View on GitHub (pinned to 0bbb338e17)