flowable/flowable-engine · error · FlowableException

transactionManager is required property for…

Error message

transactionManager is required property for SpringEventRegistryEngineConfiguration, use org.flowable.eventregistry.impl.cfg.StandaloneEventRegistryEngineConfiguration otherwise

What it means

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.

Solutions

  1. Set the transactionManager property on the configuration to your Spring PlatformTransactionManager bean.
  2. If you are not running inside Spring, switch to org.flowable.eventregistry.impl.cfg.StandaloneEventRegistryEngineConfiguration.
  3. Ensure the referenced transaction manager bean itself is defined (e.g. DataSourceTransactionManager) and not null at build time.

Example fix

// before
SpringEventRegistryEngineConfiguration cfg = new SpringEventRegistryEngineConfiguration();
cfg.setDataSource(dataSource);

// after
SpringEventRegistryEngineConfiguration cfg = new SpringEventRegistryEngineConfiguration();
cfg.setDataSource(dataSource);
cfg.setTransactionManager(transactionManager);
Defensive patterns

Strategy: validation

Validate before calling

if (cfg instanceof SpringEventRegistryEngineConfiguration springCfg && springCfg.getTransactionManager() == null) {
    throw new IllegalArgumentException("Set transactionManager or use StandaloneEventRegistryEngineConfiguration");
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/dcddb882037b38c5. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-event-registry-spring/src/main/java/org/flowable/eventregistry/spring/SpringEventRegistryEngineConfiguration.java:100

            beans = new SpringBeanFactoryProxyMap(applicationContext);
        }
    }

    public void setTransactionSynchronizationAdapterOrder(Integer transactionSynchronizationAdapterOrder) {
        this.transactionSynchronizationAdapterOrder = transactionSynchronizationAdapterOrder;
    }

    @Override
    public void initDefaultCommandConfig() {
        if (defaultCommandConfig == null) {
            defaultCommandConfig = new CommandConfig().setContextReusePossible(true);
        }
    }

    @Override
    public CommandInterceptor createTransactionInterceptor() {
        if (transactionManager == null) {
            throw new FlowableException("transactionManager is required property for SpringEventRegistryEngineConfiguration, use " + StandaloneEventRegistryEngineConfiguration.class.getName() + " otherwise");
        }

        return new SpringTransactionInterceptor(transactionManager);
    }

    @Override
    public void initTransactionContextFactory() {
        if (transactionContextFactory == null && transactionManager != null) {
            transactionContextFactory = new SpringTransactionContextFactory(transactionManager, transactionSynchronizationAdapterOrder);
        }
    }

    protected void autoDeployResources(EventRegistryEngine eventRegistryEngine) {
        if (deploymentResources != null && deploymentResources.length > 0) {
            final AutoDeploymentStrategy<EventRegistryEngine> strategy = getAutoDeploymentStrategy(deploymentMode);
            strategy.deployResources(deploymentName, deploymentResources, eventRegistryEngine);
        }
    }

View on GitHub (pinned to d6d39ce1c6)