{"record":{"id":"85bd380c655db192","repo":"flowable/flowable-engine","slug":"there-are-results-size-event-definitions-with-85bd38","errorCode":null,"errorMessage":"There are ${results.size()} event definitions with key = '${channelDefinitionKey}' and version = '${eventVersion}' in tenant = '${tenantId}'.","messagePattern":"There are (.+?) event definitions with key = '(.+?)' and version = '(.+?)' in tenant = '(.+?)'\\.","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/persistence/entity/data/impl/MybatisChannelDefinitionDataManager.java","lineNumber":133,"sourceCode":"            return results.get(0);\n        } else if (results.size() > 1) {\n            throw new FlowableException(\"There are \" + results.size() + \" event definitions with key = '\" + channelDefinitionKey + \"' and version = '\" + eventVersion + \"'.\");\n        }\n        return null;\n    }\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    public ChannelDefinitionEntity findChannelDefinitionByKeyAndVersionAndTenantId(String channelDefinitionKey, Integer eventVersion, String tenantId) {\n        Map<String, Object> params = new HashMap<>();\n        params.put(\"channelDefinitionKey\", channelDefinitionKey);\n        params.put(\"eventVersion\", eventVersion);\n        params.put(\"tenantId\", tenantId);\n        List<ChannelDefinitionEntity> results = getDbSqlSession().selectList(\"selectChannelDefinitionsByKeyAndVersionAndTenantId\", params);\n        if (results.size() == 1) {\n            return results.get(0);\n        } else if (results.size() > 1) {\n            throw new FlowableException(\"There are \" + results.size() + \" event definitions with key = '\" + channelDefinitionKey + \"' and version = '\" + eventVersion + \"' in tenant = '\" + tenantId + \"'.\");\n        }\n        return null;\n    }\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    public List<ChannelDefinition> findChannelDefinitionsByNativeQuery(Map<String, Object> parameterMap) {\n        return getDbSqlSession().selectListWithRawParameter(\"selectChannelDefinitionByNativeQuery\", parameterMap);\n    }\n\n    @Override\n    public long findChannelDefinitionCountByNativeQuery(Map<String, Object> parameterMap) {\n        return (Long) getDbSqlSession().selectOne(\"selectChannelDefinitionCountByNativeQuery\", parameterMap);\n    }\n\n    @Override\n    public void updateChannelDefinitionTenantIdForDeployment(String deploymentId, String newTenantId) {\n        HashMap<String, Object> params = new HashMap<>();","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/persistence/entity/data/impl/MybatisChannelDefinitionDataManager.java#L115-L151","documentation":"Thrown by MybatisChannelDefinitionDataManager.findChannelDefinitionByKeyAndVersionAndTenantId when selectChannelDefinitionsByKeyAndVersionAndTenantId returns multiple rows for the same key, version, and tenantId. Key+version+tenant should be unique; duplicates indicate inconsistent persisted channel definition data.","triggerScenarios":"Concurrent deployment of the same channel model for the same tenant on multiple nodes, both inserting a row with identical KEY_/VERSION_/TENANT_ID_.","commonSituations":"Clustered deployments without deployment locking; tenant-aware environments re-deploying the same resource on every node at startup; manual data fixes creating copies.","solutions":["Deduplicate: keep one FLW_EV_CHANNEL_DEFINITION row per (KEY_, VERSION_, TENANT_ID_) and delete the rest.","Guard tenant-scoped deployments with a lock so the same key/version is inserted only once per tenant.","Add a unique constraint on (TENANT_ID_, KEY_, VERSION_) in the event registry schema.","Make startup deployment code idempotent (check existence for the tenant before deploying)."],"exampleFix":"// before\nchannelRepositoryService.createDeployment().addClasspathResource(res).tenantId(tenantId).deploy(); // runs on every node\n// after\nif (channelRepositoryService.createChannelDefinitionQuery().channelKey(key)\n        .channelDefinitionVersion(1).tenantId(tenantId).count() == 0) {\n    channelRepositoryService.createDeployment().addClasspathResource(res).tenantId(tenantId).deploy();\n}","handlingStrategy":"validation","validationCode":"long n = eventRepositoryService.createChannelDefinitionQuery()\n    .channelKey(key).channelDefinitionVersion(version).tenantId(tenantId).count();\nif (n > 1) throw new IllegalStateException(\"duplicate tenant channel definitions for \" + key + \" v\" + version + \" tenant \" + tenantId);","typeGuard":null,"tryCatchPattern":"try {\n    ch = manager.findChannelDefinitionByKeyAndVersionAndTenantId(key, version, tenantId);\n} catch (FlowableException e) {\n    ch = dedupeTenantRowsAndRetry(key, version, tenantId);\n}","preventionTips":["Add unique constraint on (TENANT_ID_, KEY_, VERSION_) for channel definitions.","Guard tenant-scoped deployments with a lock or existence check.","Do not run the same deployment bootstrap concurrently on every node.","Audit manual data fixes that may duplicate tenant rows."],"tags":["flowable","channel-definition","multi-tenant","duplicate-data"],"backgroundTag":"database-query-failed","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}