{"record":{"id":"0efd1279c4d09405","repo":"flowable/flowable-engine","slug":"no-insert-statement-for-entity-getclass-in-th","errorCode":null,"errorMessage":"no insert statement for ${entity.getClass()} in the ibatis mapping files","messagePattern":"no insert statement for (.+?) in the ibatis mapping files","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/db/DbSqlSession.java","lineNumber":536,"sourceCode":"\n    protected void flushInsertEntities(Class<? extends Entity> entityClass, Collection<Entity> entitiesToInsert) {\n        if (entitiesToInsert.size() == 1) {\n            flushRegularInsert(entitiesToInsert.iterator().next(), entityClass);\n        } else if (Boolean.FALSE.equals(dbSqlSessionFactory.isBulkInsertable(entityClass))) {\n            for (Entity entity : entitiesToInsert) {\n                flushRegularInsert(entity, entityClass);\n            }\n        } else {\n            flushBulkInsert(entitiesToInsert, entityClass);\n        }\n    }\n\n    protected void flushRegularInsert(Entity entity, Class<? extends Entity> clazz) {\n        String insertStatement = dbSqlSessionFactory.getInsertStatement(entity);\n        insertStatement = dbSqlSessionFactory.mapStatement(insertStatement);\n\n        if (insertStatement == null) {\n            throw new FlowableException(\"no insert statement for \" + entity.getClass() + \" in the ibatis mapping files\");\n        }\n\n        LOGGER.debug(\"inserting: {}\", entity);\n        sqlSession.insert(insertStatement, entity);\n\n        // See https://activiti.atlassian.net/browse/ACT-1290\n        if (entity instanceof HasRevision) {\n            incrementRevision(entity);\n        }\n    }\n\n    protected void flushBulkInsert(Collection<Entity> entities, Class<? extends Entity> clazz) {\n        String insertStatement = dbSqlSessionFactory.getBulkInsertStatement(clazz);\n        insertStatement = dbSqlSessionFactory.mapStatement(insertStatement);\n\n        if (insertStatement == null) {\n            throw new FlowableException(\"no insert statement for \" + entities.iterator().next().getClass() + \" in the ibatis mapping files\");\n        }","sourceCodeStart":518,"sourceCodeEnd":554,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/db/DbSqlSession.java#L518-L554","documentation":"DbSqlSession.flushRegularInsert resolves the MyBatis insert statement id for an entity from DbSqlSessionFactory. If the mapping files define no insert statement for the entity's class, it throws FlowableException. This indicates an internal inconsistency: an entity was scheduled for insertion but has no corresponding SQL mapping.","triggerScenarios":"Flushing the persistence cache (flushInsertEntities/flushPersistentObjects) with a custom Entity subclass (or a new entity type) that has no 'insert<ClassName>' statement registered in the ibatis/MyBatis mapping configuration.","commonSituations":"Custom entity/EntityManager extensions plugged into the engine without adding corresponding MyBatis mapping XML; engine jar version mismatch where a mapping file is missing; misuse of the internal CommandContext/Entity API in custom commands.","solutions":["Register an insert statement for the entity class in the MyBatis mapping XML (id 'insert<SimpleClassName>') and include the mapping in dbSqlSessionFactory mappings.","Ensure all Flowable jars are the same version so no mapping files are missing.","If using a custom entity, extend the engine's entity insert logic and provide the mapping instead of relying on the default resolver.","Check the exception's entity class name and verify getInsertStatement/mapping conventions match it exactly."],"exampleFix":"// before: custom entity without mapping\npublic class MyTaskEntityImpl implements Entity { ... } // no insert mapping -> error on flush\n// after: add mapping resource\n<insert id=\"insertMyTaskEntity\" parameterType=\"com.myapp.MyTaskEntityImpl\">\n  insert into MY_TASK (ID_, NAME_) values (#{id}, #{name})\n</insert>\n// and register: factory.setMyBatisXmlMapping(\"com/myapp/MyTask.mapping.xml\");","handlingStrategy":"validation","validationCode":"// custom entity check before inserting via DbSqlSession\nString insertStatement = dbSqlSessionFactory.getInsertStatement(entity);\nif (insertStatement == null) throw new IllegalStateException(\"No MyBatis insert mapping registered for \" + entity.getClass());","typeGuard":null,"tryCatchPattern":"try { taskService.saveTask(task); } catch (FlowableException e) { if (e.getMessage().contains(\"no insert statement for\")) { log.error(\"Missing MyBatis mapping for entity class — register mapping XML\"); } throw e; }","preventionTips":["Register an 'insert<SimpleClassName>' MyBatis statement for every custom entity","Keep all Flowable module jars at the same version so no mapping files are missing","Use the engine's EntityManager/Entity base classes rather than inventing new entity types ad hoc","Test custom commands that persist entities in an integration test with a real database"],"tags":["mybatis","mapping","persistence","internal"],"backgroundTag":"internal-invariant-violation","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}