{"record":{"id":"dcddb882037b38c5","repo":"flowable/flowable-engine","slug":"transactionmanager-is-required-property-for-spring-dcddb8","errorCode":null,"errorMessage":"transactionManager is required property for SpringEventRegistryEngineConfiguration, use org.flowable.eventregistry.impl.cfg.StandaloneEventRegistryEngineConfiguration otherwise","messagePattern":"transactionManager is required property for SpringEventRegistryEngineConfiguration, use org\\.flowable\\.eventregistry\\.impl\\.cfg\\.StandaloneEventRegistryEngineConfiguration otherwise","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/SpringEventRegistryEngineConfiguration.java","lineNumber":100,"sourceCode":"            beans = new SpringBeanFactoryProxyMap(applicationContext);\n        }\n    }\n\n    public void setTransactionSynchronizationAdapterOrder(Integer transactionSynchronizationAdapterOrder) {\n        this.transactionSynchronizationAdapterOrder = transactionSynchronizationAdapterOrder;\n    }\n\n    @Override\n    public void initDefaultCommandConfig() {\n        if (defaultCommandConfig == null) {\n            defaultCommandConfig = new CommandConfig().setContextReusePossible(true);\n        }\n    }\n\n    @Override\n    public CommandInterceptor createTransactionInterceptor() {\n        if (transactionManager == null) {\n            throw new FlowableException(\"transactionManager is required property for SpringEventRegistryEngineConfiguration, use \" + StandaloneEventRegistryEngineConfiguration.class.getName() + \" otherwise\");\n        }\n\n        return new SpringTransactionInterceptor(transactionManager);\n    }\n\n    @Override\n    public void initTransactionContextFactory() {\n        if (transactionContextFactory == null && transactionManager != null) {\n            transactionContextFactory = new SpringTransactionContextFactory(transactionManager, transactionSynchronizationAdapterOrder);\n        }\n    }\n\n    protected void autoDeployResources(EventRegistryEngine eventRegistryEngine) {\n        if (deploymentResources != null && deploymentResources.length > 0) {\n            final AutoDeploymentStrategy<EventRegistryEngine> strategy = getAutoDeploymentStrategy(deploymentMode);\n            strategy.deployResources(deploymentName, deploymentResources, eventRegistryEngine);\n        }\n    }","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/SpringEventRegistryEngineConfiguration.java#L82-L118","documentation":"SpringEventRegistryEngineConfiguration.createTransactionInterceptor() requires a Spring PlatformTransactionManager to build a SpringTransactionInterceptor. When transactionManager is null it throws, telling the user to either set the property or use the standalone (non-Spring) configuration class, which does not need a transaction manager.","triggerScenarios":"Building an engine from a SpringEventRegistryEngineConfiguration whose transactionManager property was never set (or was set to null) and whose configuration reaches command-interceptor creation (e.g. buildEngine).","commonSituations":"Forgetting the <property name=\"transactionManager\" ref=\"...\"/> in Spring XML; constructing the configuration programmatically without setTransactionManager; using SpringEventRegistryEngineConfiguration in a non-Spring app where StandaloneEventRegistryEngineConfiguration was intended.","solutions":["Set the transactionManager property on the configuration to your Spring PlatformTransactionManager bean.","If you are not running inside Spring, switch to org.flowable.eventregistry.impl.cfg.StandaloneEventRegistryEngineConfiguration.","Ensure the referenced transaction manager bean itself is defined (e.g. DataSourceTransactionManager) and not null at build time."],"exampleFix":"// before\nSpringEventRegistryEngineConfiguration cfg = new SpringEventRegistryEngineConfiguration();\ncfg.setDataSource(dataSource);\n\n// after\nSpringEventRegistryEngineConfiguration cfg = new SpringEventRegistryEngineConfiguration();\ncfg.setDataSource(dataSource);\ncfg.setTransactionManager(transactionManager);","handlingStrategy":"validation","validationCode":"if (cfg instanceof SpringEventRegistryEngineConfiguration springCfg && springCfg.getTransactionManager() == null) {\n    throw new IllegalArgumentException(\"Set transactionManager or use StandaloneEventRegistryEngineConfiguration\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always wire transactionManager in Spring XML templates for SpringEventRegistryEngineConfiguration.","Use StandaloneEventRegistryEngineConfiguration outside Spring-managed transactions.","Add a startup smoke test that builds the engine configuration."],"tags":["spring","transaction","configuration","event-registry"],"backgroundTag":"missing-required-config-field","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}