flowable/flowable-engine · error · FlowableException
no delete statement for ${entity.getClass()} in the ibatis m
Error message
no delete statement for ${entity.getClass()} in the ibatis mapping files What it means
Thrown by DbSqlSession.flushDeleteEntities when the delete statement for the entity class resolves to null after statement mapping. No ibatis delete statement is registered for the entity type being deleted.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/db/DbSqlSession.java:682
deletedObjects.clear();
bulkDeleteOperations.clear();
}
protected void flushBulkDeletes(Class<? extends Entity> entityClass, List<BulkDeleteOperation> deleteOperations) {
// Bulk deletes
if (deleteOperations != null) {
for (BulkDeleteOperation bulkDeleteOperation : deleteOperations) {
bulkDeleteOperation.execute(sqlSession, entityClass);
}
}
}
protected void flushDeleteEntities(Class<? extends Entity> entityClass, Collection<Entity> entitiesToDelete) {
for (Entity entity : entitiesToDelete) {
String deleteStatement = dbSqlSessionFactory.getDeleteStatement(entity.getClass());
deleteStatement = dbSqlSessionFactory.mapStatement(deleteStatement);
if (deleteStatement == null) {
throw new FlowableException("no delete statement for " + entity.getClass() + " in the ibatis mapping files");
}
// It only makes sense to check for optimistic locking exceptions
// for objects that actually have a revision
if (entity instanceof HasRevision) {
int nrOfRowsDeleted = sqlSession.delete(deleteStatement, entity);
if (nrOfRowsDeleted == 0) {
throw new FlowableOptimisticLockingException(entity + " was updated by another transaction concurrently");
}
} else {
sqlSession.delete(deleteStatement, entity);
}
}
}
@Override
public void close() {
sqlSession.close();View on GitHub (pinned to d6d39ce1c6)
Solutions
- Add the delete statement to the entity's ibatis mapping XML.
- Register the delete statement name in DbSqlSessionFactory (setDeleteStatement) for the entity class.
- Verify the mapper XML is on the classpath and included in the MyBatis configuration.
- Compare against a built-in entity's mapping to ensure statement id and parameter conventions match.
Example fix
// before
// no delete in mapper -> null statement
// after
<delete id="deleteMyEntity" parameterType="...">DELETE FROM MY_ENTITY WHERE ID_ = #{id} AND REV_ = #{revision}</delete> Defensive patterns
Strategy: retry
Validate before calling
long cnt = taskService.createTaskQuery().taskId(id).count();
if (cnt == 0) throw new IllegalStateException("Task gone: " + id);
// reload entity right before modification so revision is fresh
Task fresh = taskService.createTaskQuery().taskId(id).singleResult();
fresh.setName(name); Try / catch
try { /* modify + save */ }
catch (FlowableOptimisticLockingException e) {
// reload entity with fresh revision and retry the whole command (bounded retries)
} Prevention
- Reload entities from the engine immediately before modifying; don't cache across transactions.
- Use exclusive jobs for async work touching shared process data.
- Keep user-facing transactions short.
- Design handlers idempotently so safe retries are possible.
When it happens
Trigger: Deleting an entity (Entity.remove / persistence API) whose class has no delete statement name registered in DbSqlSessionFactory, or whose mapping XML lacks the delete statement.
Common situations: Custom entities with incomplete mapper XML (insert present, delete missing); mappings not deployed after an upgrade; class name changes breaking statement lookup.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- no insert statement for ${entities.iterator().next().getClas
- no update statement for ${updatedObject.getClass()} in the i
- no delete statement for <persistentObjectClass> in the ibati
- couldn't get table counts
- couldn't get flowable table names using metadata: " + e.getM
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2191f5763a6cde7a.
Report an issue: GitHub.