jd-opensource/joyagent-jdgenie · error · CatalogException

获取数据库表失败

Error message

获取数据库表失败

What it means

H2SqlCatalog.listTables wraps any SQLException from the H2 metadata query into CatalogException with the message '获取数据库表失败'. It means listing tables of an H2 database failed at the JDBC level; the cause carries the precise SQL error.

Solutions

  1. Confirm the H2 database/schema exists and identifiers match H2's case rules (use uppercase or quoted names).
  2. Check the JDBC URL (mem vs file mode) and that the database is still open.
  3. Inspect the cause SQLException for the concrete H2 error code.
  4. Ensure no other process holds an exclusive lock on the H2 file database.

Example fix

// before
catalog.listTables("my_schema"); // H2 may store it as MY_SCHEMA
// after
catalog.listTables("MY_SCHEMA"); // match H2's default upper-case identifiers
Defensive patterns

Strategy: try-catch

Validate before calling

// Java: verify DB/schema reachable before listing
try (Connection c = DriverManager.getConnection(url, user, pass)) {
    ResultSet rs = c.createStatement().executeQuery(
        "SELECT COUNT(*) FROM INFORMATION_SCHEMA.SCHEMATA WHERE UPPER(SCHEMA_NAME)=UPPER('" + schema + "')");
    rs.next();
    if (rs.getInt(1) == 0) throw new IllegalStateException("schema not found: " + schema);
}

Try / catch

try {
    List<SimpleTable> tables = h2Catalog.listTables(schema);
} catch (CatalogException e) {
    log.error("H2 listTables failed: {}", e.getCause().getMessage(), e);
}

Prevention

When it happens

Trigger: Calling listTables(schema) when the H2 connection is closed, the schema does not exist, or the query against H2 information schema throws an SQLException.

Common situations: H2 in-memory database dropped after connection close, wrong schema name (H2 uppercases unquoted identifiers), H2 file locked by another process, or H2 version mismatch between writer and reader.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of jd-opensource/joyagent-jdgenie@2417e0b8b6 (2026-09-08). Data as JSON: /api/errors/e4b7066c32258db2. Report an issue: GitHub.

Appendix: source

Thrown at genie-backend/src/main/java/com/jd/genie/data/jdbc/catalog/h2/H2SqlCatalog.java:45

        SYS_DATABASES.add("mysql");
        SYS_DATABASES.add("performance_schema");
        SYS_DATABASES.add("sys");
    }

    @Override
    public List<SimpleTable> listTables(Connection connection, String schema) throws CatalogException {
        String sql = "show tables ";
        try (PreparedStatement prepared = connection.prepareStatement(sql);
             ResultSet rs = prepared.executeQuery()) {
            List<SimpleTable> tables = new ArrayList<>();
            while (rs.next()) {
                SimpleTable st = new SimpleTable();
                st.setTableName(rs.getString(1));
                tables.add(st);
            }
            return tables;
        } catch (SQLException e) {
            throw new CatalogException("获取数据库表失败", e);
        }
    }

    public String typeConvertMysql(String type) {
        return switch (type) {
            case "DATE", "TIME", "TIMESTAMP" -> StandardColumnType.DATE.name();
            case "TINYINT", "SMALLINT", "INTEGER", "BIGINT", "FLOAT", "DOUBLE", "NUMERIC", "DECIMAL" ->
                    StandardColumnType.DECIMAL.name();
            default -> StandardColumnType.VARCHAR.name();
        };
    }

    @Override
    public List<TableColumn> getTableColumns(Connection connection, String tablePath, String schema) throws CatalogException {
        String sql = String.format(
                SELECT_COLUMNS_SQL_TEMPLATE, "PUBLIC", tablePath.toUpperCase());

        try (Statement prepared = connection.createStatement();

View on GitHub (pinned to 2417e0b8b6)