Is your feature request related to a problem? Please describe.
When flowable-spring-boot-starter-process is used alongside spring-boot-starter-flyway (or any other Spring Boot–managed DB initializer: Liquibase, spring.sql.init), there is no guaranteed bean-instantiation order between Flowable's processEngine and Flyway's flywayInitializer. Spring Boot's DatabaseInitializationDependencyConfigurer is the framework's mechanism for this — it walks beans flagged by registered DependsOnDatabaseInitializationDetector SPI implementations and adds @DependsOn(flywayInitializer) to each.
Spring Boot ships detectors for EntityManagerFactory, JdbcOperations, JobRepository, etc. flowable-spring-boot-autoconfigure does not register one for processEngine, and ProcessEngineAutoConfiguration does not annotate the bean with @DependsOnDatabaseInitialization. As a result, Flowable can be instantiated before Flyway, creates its ACT_* tables into an empty schema, and Flyway then refuses to start because the schema is non-empty but contains no flyway_schema_history row.
This often went unnoticed in Spring Boot 3 because HibernateJpaAutoConfiguration indirectly delayed Flowable through the JPA bean graph. With Spring Boot 4's modularised autoconfig — and projects increasingly dropping JPA in favour of plain JDBC, jOOQ, or Exposed — that incidental ordering vanishes and the race surfaces deterministically.
Steps to reproduce on Spring Boot 4.0.6 / Flowable 8.0.0:
spring-boot-starter-jdbc + spring-boot-starter-flyway + flowable-spring-boot-starter-process on the classpath.
- No
spring-boot-starter-data-jpa.
- Empty database, one Flyway migration in
db/migration/.
- Boot the app. Flyway fails with
Schema "public" is not empty because Flowable created ACT_* first.
Describe the solution you'd like
Register a DependsOnDatabaseInitializationDetector in flowable-spring-boot-autoconfigure that returns the names of the engine beans whose definitions are present (processEngine, and analogously cmmnEngine, dmnEngine, appEngine, etc.).
Concrete change — one class plus one META-INF/spring.factories entry inside flowable-spring-boot-autoconfigure:
public class FlowableDependsOnDatabaseInitializationDetector
implements DependsOnDatabaseInitializationDetector {
private static final String[] ENGINE_BEANS = {
"processEngine", "cmmnEngine", "dmnEngine", "appEngine", "idmEngine", "eventRegistryEngine"
};
@Override
public Set<String> detect(ConfigurableListableBeanFactory beanFactory) {
Set<String> names = new HashSet<>();
for (String name : ENGINE_BEANS) {
if (beanFactory.containsBeanDefinition(name)) {
names.add(name);
}
}
return names;
}
}
# META-INF/spring.factories
org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\
org.flowable.spring.boot.FlowableDependsOnDatabaseInitializationDetector
This is the same approach Spring Boot itself uses to wire EntityManagerFactory and JdbcOperations behind Flyway. No behaviour change for existing users who don't have Flyway/Liquibase on the classpath — the configurer is a no-op when no DB initializer is present.
Describe alternatives you've considered
@DependsOnDatabaseInitialization on the bean definitions in ProcessEngineAutoConfiguration. Equivalent effect, slightly less flexible than the SPI (e.g. a user can't opt out, and you can't easily detect bean presence conditionally).
@AutoConfigureAfter(FlywayAutoConfiguration.class) on ProcessEngineAutoConfiguration. Doesn't work — that ordering controls auto-config class processing, not bean instantiation.
- Each consumer registers their own detector. What we're currently doing in our service — a one-class detector that names
processEngine. Works, but every Flowable+Flyway user ends up duplicating it.
- Disable
flowable.database-schema-update and ship ACT_* DDL as Flyway migrations. Most correct from a schema-ownership perspective but high maintenance — every Flowable bump requires copying upgrade scripts from org/flowable/common/db/upgrade/*.sql and revalidating.
Additional context
I'm happy to open a PR with the change above if the maintainers agree this is the right shape — just let me know whether you'd prefer the detector in flowable-spring-boot-autoconfigure next to the engine autoconfigs, or split per-engine module.
Is your feature request related to a problem? Please describe.
When
flowable-spring-boot-starter-processis used alongsidespring-boot-starter-flyway(or any other Spring Boot–managed DB initializer: Liquibase,spring.sql.init), there is no guaranteed bean-instantiation order between Flowable'sprocessEngineand Flyway'sflywayInitializer. Spring Boot'sDatabaseInitializationDependencyConfigureris the framework's mechanism for this — it walks beans flagged by registeredDependsOnDatabaseInitializationDetectorSPI implementations and adds@DependsOn(flywayInitializer)to each.Spring Boot ships detectors for
EntityManagerFactory,JdbcOperations,JobRepository, etc.flowable-spring-boot-autoconfiguredoes not register one forprocessEngine, andProcessEngineAutoConfigurationdoes not annotate the bean with@DependsOnDatabaseInitialization. As a result, Flowable can be instantiated before Flyway, creates itsACT_*tables into an empty schema, and Flyway then refuses to start because the schema is non-empty but contains noflyway_schema_historyrow.This often went unnoticed in Spring Boot 3 because
HibernateJpaAutoConfigurationindirectly delayed Flowable through the JPA bean graph. With Spring Boot 4's modularised autoconfig — and projects increasingly dropping JPA in favour of plain JDBC, jOOQ, or Exposed — that incidental ordering vanishes and the race surfaces deterministically.Steps to reproduce on Spring Boot 4.0.6 / Flowable 8.0.0:
spring-boot-starter-jdbc+spring-boot-starter-flyway+flowable-spring-boot-starter-processon the classpath.spring-boot-starter-data-jpa.db/migration/.Schema "public" is not emptybecause Flowable createdACT_*first.Describe the solution you'd like
Register a
DependsOnDatabaseInitializationDetectorinflowable-spring-boot-autoconfigurethat returns the names of the engine beans whose definitions are present (processEngine, and analogouslycmmnEngine,dmnEngine,appEngine, etc.).Concrete change — one class plus one
META-INF/spring.factoriesentry insideflowable-spring-boot-autoconfigure:This is the same approach Spring Boot itself uses to wire
EntityManagerFactoryandJdbcOperationsbehind Flyway. No behaviour change for existing users who don't have Flyway/Liquibase on the classpath — the configurer is a no-op when no DB initializer is present.Describe alternatives you've considered
@DependsOnDatabaseInitializationon the bean definitions inProcessEngineAutoConfiguration. Equivalent effect, slightly less flexible than the SPI (e.g. a user can't opt out, and you can't easily detect bean presence conditionally).@AutoConfigureAfter(FlywayAutoConfiguration.class)onProcessEngineAutoConfiguration. Doesn't work — that ordering controls auto-config class processing, not bean instantiation.processEngine. Works, but every Flowable+Flyway user ends up duplicating it.flowable.database-schema-updateand shipACT_*DDL as Flyway migrations. Most correct from a schema-ownership perspective but high maintenance — every Flowable bump requires copying upgrade scripts fromorg/flowable/common/db/upgrade/*.sqland revalidating.Additional context
org.springframework.boot.autoconfigure.orm.jpa.JpaDependsOnDatabaseInitializationDetectorandorg.springframework.boot.autoconfigure.jdbc.JdbcOperationsDependsOnDatabaseInitializationDetector— those are good reference implementations.I'm happy to open a PR with the change above if the maintainers agree this is the right shape — just let me know whether you'd prefer the detector in
flowable-spring-boot-autoconfigurenext to the engine autoconfigs, or split per-engine module.