hs-web/hsweb-framework · error · IllegalStateException

table " + table.getName() + " not found in join

Error message

table " + table.getName() + " not found in join

What it means

During column visiting, the analyzer maps a column's table alias to a previously registered join via `joins.get(alias)`. When an alias referenced in the SELECT list was never registered by a JOIN clause, the lookup returns null and an IllegalStateException is thrown, indicating the query references a table that is not part of the FROM/JOIN structure the analyzer built.

Solutions

  1. Ensure every alias used to qualify columns has a corresponding `JOIN table alias` clause in the query.
  2. Remove or correct the stale alias in the SELECT list.
  3. Check alias quoting: use the same spelling (no extra quotes/backticks) in the JOIN and in column qualifiers.

Example fix

// before
"select t2.name from user t1"
// after
"select t2.name from user t1 join role t2 on t1.id = t2.user_id"
Defensive patterns

Strategy: validation

Validate before calling

Set<String> aliases = extractJoinAliases(sql); for (String q : extractColumnQualifiers(sql)) { if (!aliases.contains(q) && !q.equals(fromAlias)) { throw new IllegalArgumentException("unknown alias: " + q); } }

Try / catch

try { analyzer.analyze(dql); } catch (IllegalStateException e) { if (e.getMessage().contains("not found in join")) { log.warn("stale alias in query: {}", e.getMessage()); } throw e; }

Prevention

When it happens

Trigger: Running an analyzed query whose SELECT list qualifies a column with an alias (`t1.name`) that appears neither in FROM nor in any JOIN clause, or where the join alias differs (case/`parsePlainName` stripping) from the qualifier used.

Common situations: Copy-pasted SQL with leftover aliases after removing a JOIN; dynamically assembled query builders emitting stale aliases; aliases created via quoted or backtick-quoted identifiers that parsePlainName strips differently.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of hs-web/hsweb-framework@b2cfc85a57 (2026-09-13). Data as JSON: /api/errors/d180792350f81598. Report an issue: GitHub.

Appendix: source

Thrown at hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/query/QueryAnalyzerImpl.java:464

            }
        }
    }

    @Override
    public void visit(AllTableColumns allTableColumns) {
        net.sf.jsqlparser.schema.Table table = allTableColumns.getTable();

        String name = table.getName();

        if (Objects.equals(select.table.alias, name)) {
            putSelectColumns(select.table, select.columnList);
            return;
        }

        QueryAnalyzer.Join join = joins.get(parsePlainName(table.getName()));

        if (join == null) {
            throw new IllegalStateException("table " + table.getName() + " not found in join");
        }
        putSelectColumns(join.table, select.columnList);
    }

    private QueryAnalyzer.Table getTable(net.sf.jsqlparser.schema.Table table) {
        QueryAnalyzer.Table meta;
        if (null == table) {
            return select.table;
        }
        String tableName = parsePlainName(table.getName());

        if (Objects.equals(tableName, select.table.alias)) {
            meta = select.table;
        } else {
            QueryAnalyzer.Join join = joins.get(tableName);
            if (join == null) {
                throw new IllegalStateException("table " + table + " not found in from or join");
            }

View on GitHub (pinned to b2cfc85a57)