Skip to content

fix: select contexts by contextIds regardless of fullyQualifiedTableNames - #1551

Merged
jeffgbutler merged 2 commits into
mybatis:masterfrom
mvanhorn:fix/contextids-empty-tablenames
Jul 25, 2026
Merged

fix: select contexts by contextIds regardless of fullyQualifiedTableNames#1551
jeffgbutler merged 2 commits into
mybatis:masterfrom
mvanhorn:fix/contextids-empty-tablenames

Conversation

@mvanhorn

Copy link
Copy Markdown
Contributor

Summary

Fixes #1547: when a caller supplies contextIds but no fullyQualifiedTableNames, MyBatis Generator ignores the contextIds and runs every context instead of the requested subset. This restores the pre-2.0 selection behavior. The regression was confirmed by @jeffgbutler in the issue thread.

Background

MyBatisGenerator.calculateContextsToRun() decides whether to run all configured contexts or only the subset named in contextIds. In 2.0 it branches on whether fullyQualifiedTableNames is empty:

if (fullyQualifiedTableNames.isEmpty()) {
    contextsToRun = configuration.getContexts();          // run everything
} else {
    contextsToRun = configuration.getContexts().stream()
            .filter(c -> contextIds.contains(c.getId()))
            .toList();
}

Context selection and table-name filtering are independent concerns — the table names are applied later, during introspection in runContextIntrospection. Tying context selection to the table-name set means that calling generate(callback, contextIds, Collections.emptySet()) runs every context, ignoring contextIds. In 1.4.2 and earlier the subset selection worked as expected.

Fix

Branch on contextIds.isEmpty() instead:

if (contextIds.isEmpty()) {
    contextsToRun = configuration.getContexts();
} else {
    contextsToRun = configuration.getContexts().stream()
            .filter(c -> contextIds.contains(c.getId()))
            .toList();
}

contextIds is a final, non-null HashSet, so no null guard is needed. The "run all contexts" branch is now taken only when no contextIds are specified, regardless of whether table names are also supplied.

Testing

Added a database-free unit test that invokes the private calculateContextsToRun() via reflection (validation runs inside generate(), so a MyBatisGenerator built with minimal contexts needs no live database) and covers three cases:

  • contextIds supplied, no table names → only the requested context runs (the reported regression);
  • no contextIds → all contexts run;
  • contextIds supplied together with a table name → still only the requested context.

MyBatisGeneratorTest passes with the fix; the new test fails against the unpatched code (it runs both contexts), confirming it catches the regression.

Closes #1547

AI was used for assistance.

…ames

calculateContextsToRun() branched on fullyQualifiedTableNames.isEmpty()
to decide whether to run all contexts or only the ones named in
contextIds. As a result, supplying contextIds without any
fullyQualifiedTableNames ran every context instead of the requested
subset, a regression from 1.4.2 and earlier.

Context selection and table-name filtering are independent concerns: the
table names are applied later during introspection. Branch on
contextIds.isEmpty() so the requested contexts are honored whether or not
table names are also supplied. contextIds is a final, non-null HashSet, so
no null guard is needed.

Adds a database-free test that invokes calculateContextsToRun() via
reflection and covers contextIds-only, no-contextIds, and
contextIds-with-table-name.

Closes mybatis#1547

@jeffgbutler jeffgbutler left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use reflection for testing. Make the method under test have package private visibility, then tests in the same package can see it.

Make the method under test package private and move the test into the
same package so it can call it directly, as requested in review.
@mvanhorn

Copy link
Copy Markdown
Contributor Author

Done in f1671a4. The method is package private now and the test moved into org.mybatis.generator.api so it calls it directly, no reflection. Core suite still passes (1289 tests).

@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 92.535%. remained the same — mvanhorn:fix/contextids-empty-tablenames into mybatis:master

@jeffgbutler jeffgbutler added this to the 2.1.0 milestone Jul 25, 2026
@jeffgbutler
jeffgbutler merged commit d2c83fe into mybatis:master Jul 25, 2026
2 checks passed
@jeffgbutler

Copy link
Copy Markdown
Member

Thanks!

@mvanhorn

Copy link
Copy Markdown
Contributor Author

Thanks for getting this in. Appreciate you taking the contextIds selection fix so callers do not have to pass table names too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

contextIds is ignored when fullyQualifiedTableNames is empty

3 participants