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
- Read getCause() of the DaoException to find the real exception thrown inside the callable and fix that root problem.
- Make the callable null-safe: validate entity objects, field values, and any external inputs before calling them.
- Move expensive validation before the transaction so only fail-safe DB writes remain inside the callable.
- 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
- Validate all inputs and entities before entering the transaction
- Always inspect DaoException.getCause() — the message 'Callable failed' is only a wrapper
- Keep the callable small and free of business-logic throws
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
- Expected unique result, but count was
- Cannot delete entity, key is null
- Entity does not exist in the database anymore
- Cannot update entity without key - was it inserted before?
- ( ) does not have a single-column primary key
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)