YunaiV/yudao-cloud · error · UnexpectedLiquibaseException

Cannot determine the Oracle database version number

Error message

Cannot determine the Oracle database version number

What it means

Thrown by a Liquibase patch for the DM (Dameng) database, emulating Oracle behavior in DmDatabase.getIdentifierMaximumLength(). It calls getDatabaseMajorVersion() to decide whether identifiers are limited to 30 bytes (pre-12c Oracle) or 128 bytes (12c+). When the underlying version query fails, the DatabaseException is wrapped in UnexpectedLiquibaseException with this message.

Source

Thrown at sql/dm/flowable-patch/src/main/java/liquibase/database/core/DmDatabase.java:594

    /**
     * Returns the maximum number of bytes (NOT: characters) for an identifier. For Oracle <=12c Release 20, this
     * is 30 bytes, and starting from 12cR2, up to 128 (except for tablespaces, PDB names and some other rather rare
     * object types).
     *
     * @return the maximum length of an object identifier, in bytes
     */
    public int getIdentifierMaximumLength() {
        try {
            if (getDatabaseMajorVersion() < ORACLE_12C_MAJOR_VERSION) {
                return SHORT_IDENTIFIERS_LENGTH;
            } else if ((getDatabaseMajorVersion() == ORACLE_12C_MAJOR_VERSION) && (getDatabaseMinorVersion() <= 1)) {
                return SHORT_IDENTIFIERS_LENGTH;
            } else {
                return LONG_IDENTIFIERS_LEGNTH;
            }
        } catch (DatabaseException ex) {
            throw new UnexpectedLiquibaseException("Cannot determine the Oracle database version number", ex);
        }

    }
}

View on GitHub (pinned to 477be9dd49)

Solutions

  1. Check the chained cause (DatabaseException) for the real failure: closed connection, privilege, or version-parse error.
  2. Verify DM JDBC connectivity from the same process (simple SELECT 1) and that the connection is still open when Liquibase runs.
  3. Use a DM driver / DM compatibility mode (e.g. COMPATIBLE=ORACLE) whose DatabaseMetaData reports a version string Liquibase can parse.
  4. If the DM version is fixed and known, subclass DmDatabase and override getIdentifierMaximumLength() to return the constant directly.

Example fix

// before
Database db = ...; // DmDatabase
int len = db.getIdentifierMaximumLength(); // may throw

// after
if (db instanceof DmDatabase) {
    try {
        len = db.getIdentifierMaximumLength();
    } catch (UnexpectedLiquibaseException e) {
        len = 30; // DM default: short identifiers
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check connectivity before running Liquibase
try (Connection c = dataSource.getConnection();
     Statement s = c.createStatement();
     ResultSet rs = s.executeQuery("SELECT 1")) {
    // connection usable; version metadata likely reachable
}

Try / catch

try {
    int len = database.getIdentifierMaximumLength();
} catch (UnexpectedLiquibaseException e) {
    if (e.getMessage().contains("Oracle database version")) {
        log.warn("Falling back to 30-byte identifiers; check DM driver", e.getCause());
        len = 30;
    } else throw e;
}

Prevention

When it happens

Trigger: Liquibase runs getIdentifierMaximumLength() (e.g. when comparing/normalizing object names in a changeset) against a DM database and the JDBC connection cannot execute the version query: connection already closed, DM driver incompatibility, insufficient privileges, or an unparseable version string from DatabaseMetaData.getDatabaseProductVersion().

Common situations: Running Flowable/Liquibase on DM (Dameng) with a driver version that does not report Oracle-compatible version strings; pooled connection that was invalidated between checkout and use; DM compatibility mode set to a non-Oracle mode so the version query returns unexpected output.

Related errors


AI-assisted analysis of YunaiV/yudao-cloud@477be9dd49 (2026-08-14). Data as JSON: /api/errors/b0fd4b2d1a080dbe. Report an issue: GitHub.