{"record":{"id":"26a7b816bb4b1582","repo":"YunaiV/yudao-cloud","slug":"couldn-t-deduct-database-type-from-database-produc","errorCode":null,"errorMessage":"couldn't deduct database type from database product name '{}'","messagePattern":"couldn't deduct database type from database product name '(.+?)'","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"critical","filePath":"sql/dm/flowable-patch/src/main/java/org/flowable/common/engine/impl/AbstractEngineConfiguration.java","lineNumber":522,"sourceCode":"            // CRDB does not expose the version through the jdbc driver, so we need to fetch it through version().\n            if (PRODUCT_NAME_POSTGRES.equalsIgnoreCase(databaseProductName)) {\n                try (PreparedStatement preparedStatement = connection.prepareStatement(\"select version() as version;\");\n                     ResultSet resultSet = preparedStatement.executeQuery()) {\n                    String version = null;\n                    if (resultSet.next()) {\n                        version = resultSet.getString(\"version\");\n                    }\n\n                    if (StringUtils.isNotEmpty(version) && version.toLowerCase().startsWith(PRODUCT_NAME_CRDB.toLowerCase())) {\n                        databaseProductName = PRODUCT_NAME_CRDB;\n                        logger.info(\"CockroachDB version '{}' detected\", version);\n                    }\n                }\n            }\n\n            databaseType = databaseTypeMappings.getProperty(databaseProductName);\n            if (databaseType == null) {\n                throw new FlowableException(\"couldn't deduct database type from database product name '\" + databaseProductName + \"'\");\n            }\n            logger.debug(\"using database type: {}\", databaseType);\n\n        } catch (SQLException e) {\n            throw new RuntimeException(\"Exception while initializing Database connection\", e);\n        } finally {\n            try {\n                if (connection != null) {\n                    connection.close();\n                }\n            } catch (SQLException e) {\n                logger.error(\"Exception while closing the Database connection\", e);\n            }\n        }\n\n        // Special care for MSSQL, as it has a hard limit of 2000 params per statement (incl bulk statement).\n        // Especially with executions, with 100 as default, this limit is passed.\n        if (DATABASE_TYPE_MSSQL.equals(databaseType)) {","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/YunaiV/yudao-cloud/blob/477be9dd49ab7223a972a6abdff0684d6423dec3/sql/dm/flowable-patch/src/main/java/org/flowable/common/engine/impl/AbstractEngineConfiguration.java#L504-L540","documentation":"Flowable reads DatabaseMetaData.getDatabaseProductName() and maps it to an internal databaseType via the databaseTypeMappings Properties table. If the product name (after CockroachDB special-casing) has no entry, it throws this FlowableException showing the unrecognized name.","triggerScenarios":"Connecting to a database whose product name is not a key in the built-in mappings — e.g. 'DM DBMS' from Dameng, 'OSCAR', a new Derby/H2 version string, or a proxy/wrapper driver that reports its own name. Only names like Oracle, MySQL, PostgreSQL, H2, SQL Server, DB2, etc. are mapped by default.","commonSituations":"Using DM (Dameng) or another national database with unpatched Flowable; a vendor-patched driver that changes DatabaseMetaData.getDatabaseProductName(); running against a database fork whose name string drifted (e.g. 'PostgreSQL-XL').","solutions":["Set the database type explicitly so the mapping lookup is skipped: cfg.setDatabaseType(\"oracle\") (or the closest compatible type).","Add a mapping before engine build: cfg.setDatabaseTypeMappings(custom) or databaseTypeMappings.put('<product name>', 'oracle') on the configuration.","Patch the driver/URL so the product name matches an expected key (some DM drivers accept a compatibility flag that reports 'Oracle').","Verify the actual name via a quick JDBC snippet printing metaData.getDatabaseProductName()."],"exampleFix":"// before\nProcessEngineConfiguration cfg = ...; // auto-detect fails on DM DBMS\n\n// after\nProcessEngineConfiguration cfg = ...;\ncfg.setDatabaseType(\"oracle\"); // DM is Oracle-compatible","handlingStrategy":"validation","validationCode":"try (Connection c = ds.getConnection()) {\n    String product = c.getMetaData().getDatabaseProductName();\n    String type = databaseTypeMappings.getProperty(product);\n    if (type == null) type = \"oracle\"; // DM fallback\n    cfg.setDatabaseType(type); // bypass auto-detection\n}","typeGuard":null,"tryCatchPattern":"try { engine = cfg.buildProcessEngine(); }\ncatch (FlowableException e) {\n    if (e.getMessage().contains(\"couldn't deduct database type\")) {\n        cfg.setDatabaseType(\"oracle\"); // retry once with explicit type\n        engine = cfg.buildProcessEngine();\n    } else throw e;\n}","preventionTips":["Always set databaseType explicitly on non-mainstream databases (DM, Oscar, Kingbase)","Print getDatabaseProductName() once during environment bring-up and record it in runbooks"],"tags":["flowable","database","dameng","detection","configuration"],"backgroundTag":null,"analyzedSha":"477be9dd49ab7223a972a6abdff0684d6423dec3","analyzedAt":"2026-08-14T13:35:31.121Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}