flowable/flowable-engine · error · FlowableException
no update statement for ${updatedObject.getClass()} in the i
Error message
no update statement for ${updatedObject.getClass()} in the ibatis mapping files What it means
Thrown by DbSqlSession.flushUpdateEntity when the update statement resolved for the entity's class is null after mapping. The persistence framework could not find an ibatis update statement for the entity about to be updated during command flush.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/db/DbSqlSession.java:615
if (!bulkUpdateOperations.isEmpty()) {
bulkUpdateOperations.forEach(this::flushBulkUpdate);
}
if (!updatedObjects.isEmpty()) {
updatedObjects.forEach(this::flushUpdateEntity);
}
updatedObjects.clear();
bulkUpdateOperations.clear();
}
protected void flushUpdateEntity(Entity updatedObject) {
String updateStatement = dbSqlSessionFactory.getUpdateStatement(updatedObject);
updateStatement = dbSqlSessionFactory.mapStatement(updateStatement);
if (updateStatement == null) {
throw new FlowableException("no update statement for " + updatedObject.getClass() + " in the ibatis mapping files");
}
LOGGER.debug("updating: {}", updatedObject);
int updatedRecords = sqlSession.update(updateStatement, updatedObject);
if (updatedRecords == 0) {
throw new FlowableOptimisticLockingException(updatedObject + " was updated by another transaction concurrently");
}
// See https://activiti.atlassian.net/browse/ACT-1290
if (updatedObject instanceof HasRevision) {
((HasRevision) updatedObject).setRevision(((HasRevision) updatedObject).getRevisionNext());
}
}
protected void flushBulkUpdate(BulkUpdateOperation bulkUpdateOperation) {
// Bulk update
bulkUpdateOperation.execute(sqlSession);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Add the update statement to the entity's ibatis mapping XML (matching the name DbSqlSessionFactory.getUpdateStatement expects).
- Register the update statement name in DbSqlSessionFactory for the entity class.
- Confirm the mapping file is included in the MyBatis configuration/mapper locations.
- Check the entity class identity is the one the mappings were generated for (no duplicate/custom subclass).
Example fix
// before
<update id="updateMyEntity">...</update> // missing -> statement resolves to null
// after
<update id="updateMyEntity" parameterType="...">UPDATE MY_ENTITY SET ... WHERE ID_ = #{id}</update> Defensive patterns
Strategy: validation
Validate before calling
String stmt = dbSqlSessionFactory.getBulkInsertStatement(MyEntityImpl.class);
if (stmt == null || dbSqlSessionFactory.mapStatement(stmt) == null) {
throw new IllegalStateException("Register bulk insert statement for " + MyEntityImpl.class);
} Try / catch
try { flushBulkInsert(entities, MyEntityImpl.class); }
catch (FlowableException e) { if (e.getMessage().startsWith("no insert statement")) { /* fix mapping / register statement */ } throw e; } Prevention
- When adding a custom entity, copy the full mapper XML of a similar built-in entity including bulk insert.
- Add a startup test that flushes each entity type once against an in-memory DB.
- Keep all flowable module versions aligned so statement registries and mappings match.
- Name statements consistently and register them explicitly in DbSqlSessionFactory.
When it happens
Trigger: Flushing a dirty entity whose class has no update statement registered in DbSqlSessionFactory (getUpdateStatement returns null), typically a custom entity whose MyBatis mapper lacks the update statement or whose mapping file was not loaded.
Common situations: Custom Entity implementations without a full mapper XML; stale/partial mapping configuration after an upgrade; entity class renamed so statement lookup keys no longer match.
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 delete statement for ${entity.getClass()} in the ibatis m
- 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/792965530137eaff.
Report an issue: GitHub.