{"record":{"id":"73dbe19677ec503b","repo":"apache/incubator-seata","slug":"datasource-required-not-null","errorCode":null,"errorMessage":"datasource required not null!","messagePattern":"datasource required not null!","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"critical","filePath":"compatible/src/main/java/io/seata/saga/engine/config/DbStateMachineConfig.java","lineNumber":113,"sourceCode":"\n    /**\n     * Gets db type from data source.\n     *\n     * @param dataSource the data source\n     * @return the db type from data source\n     * @throws SQLException the sql exception\n     */\n    public static String getDbTypeFromDataSource(DataSource dataSource) throws SQLException {\n        try (Connection con = dataSource.getConnection()) {\n            DatabaseMetaData metaData = con.getMetaData();\n            return metaData.getDatabaseProductName();\n        }\n    }\n\n    @Override\n    public void afterPropertiesSet() throws Exception {\n        if (dataSource == null) {\n            throw new IllegalArgumentException(\"datasource required not null!\");\n        }\n\n        dbType = getDbTypeFromDataSource(dataSource);\n        if (getStateLogStore() == null) {\n            DbAndReportTcStateLogStore dbStateLogStore = new DbAndReportTcStateLogStore();\n            dbStateLogStore.setDataSource(dataSource);\n            dbStateLogStore.setTablePrefix(tablePrefix);\n            dbStateLogStore.setDbType(dbType);\n            dbStateLogStore.setDefaultTenantId(getDefaultTenantId());\n            dbStateLogStore.setSeqGenerator(getSeqGenerator());\n\n            if (StringUtils.hasLength(getSagaJsonParser())) {\n                ParamsSerializer paramsSerializer = new ParamsSerializer();\n                paramsSerializer.setJsonParserName(getSagaJsonParser());\n                dbStateLogStore.setParamsSerializer(paramsSerializer);\n            }\n\n            if (sagaTransactionalTemplate == null) {","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/apache/incubator-seata/blob/e01f97c6db397165050caa6764020410c2c8199a/compatible/src/main/java/io/seata/saga/engine/config/DbStateMachineConfig.java#L95-L131","documentation":"Thrown by DbStateMachineConfig.afterPropertiesSet (Spring InitializingBean callback) when the Saga state machine config bean is initialized without a DataSource. The DB-backed Saga engine needs a database for state-log storage, so a missing datasource is a fatal wiring error at startup.","triggerScenarios":"Creating a DbStateMachineConfig bean (via XML or @Bean) without calling setDataSource(...), or the datasource property placeholder resolving to null; also programmatic construction where afterPropertiesSet is invoked before the datasource is assigned.","commonSituations":"Spring Boot autoconfig partially overridden so the setDataSource call is dropped; property name typo (dataSource vs datasource) leaving the setter uncalled; test contexts building the config manually; migrating from in-memory to DB state log store and forgetting the datasource bean.","solutions":["Call setDataSource(...) on the DbStateMachineConfig bean before the context refreshes.","Check the property/placeholder that supplies the datasource actually resolves (no typo, profile active).","In XML config verify <property name=\"dataSource\" ref=\"...\"/> points at an existing bean.","Ensure afterPropertiesSet is not invoked manually before wiring is complete."],"exampleFix":"// before\n@Bean\npublic DbStateMachineConfig dbStateMachineConfig() {\n    DbStateMachineConfig cfg = new DbStateMachineConfig();\n    // datasource never set -> afterPropertiesSet throws\n    return cfg;\n}\n\n// after\n@Bean\npublic DbStateMachineConfig dbStateMachineConfig(DataSource dataSource) {\n    DbStateMachineConfig cfg = new DbStateMachineConfig();\n    cfg.setDataSource(dataSource);\n    return cfg;\n}","handlingStrategy":"validation","validationCode":"DbStateMachineConfig cfg = new DbStateMachineConfig();\nObjects.requireNonNull(dataSource, \"DataSource must be wired before DbStateMachineConfig init\");\ncfg.setDataSource(dataSource);","typeGuard":null,"tryCatchPattern":"try {\n    context.refresh();\n} catch (BeanInitializationException e) {\n    if (e.getCause() instanceof IllegalArgumentException\n            && String.valueOf(e.getCause().getMessage()).contains(\"datasource\")) {\n        throw new ConfigurationException(\"DbStateMachineConfig is missing its dataSource bean/property\", e);\n    }\n    throw e;\n}","preventionTips":["Wire the DataSource in the same @Bean method that constructs DbStateMachineConfig.","Add a startup assertion Objects.requireNonNull(dataSource) with a helpful message.","Validate datasource property placeholders (name, profile) before context refresh."],"tags":["saga","spring","configuration","datasource","startup"],"backgroundTag":null,"analyzedSha":"e01f97c6db397165050caa6764020410c2c8199a","analyzedAt":"2026-08-14T10:23:53.097Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}