Skip to content

Fix generated-ID row mismatches in PrepAndExpectedTestCase - #907

Merged
jeffjensen merged 1 commit into
mainfrom
672-prepandexpected-sort-filtered-columns
Aug 4, 2026
Merged

jeffjensen merged 1 commit into
mainfrom
672-prepandexpected-sort-filtered-columns

Conversation

@jeffjensen

@jeffjensen jeffjensen commented Aug 4, 2026

Copy link
Copy Markdown
Member

Summary

  • DefaultPrepAndExpectedTestCase#verifyData always sorted the actual table by all of its native columns (generated/identity column included) but the expected table by only the columns its file declares, which typically omits that column since its value is unknown ahead of time — excludeColumns/includeColumns were applied to the comparison but never to the sort. When production code doesn't guarantee row insertion order (e.g. Hibernate reordering a batch insert), this misaligns same-data rows and fails the comparison with a false DbComparisonFailure.
  • Add VerifyTableDefinition#sortOnFilteredColumnsOnly (default false, preserving prior behavior), the opt-in toggle proposed in Allow PrepAndExpectedTestCase to sort only on filtered columns instead of all columns #676: when true, both tables sort by only their excludeColumns/includeColumns-filtered columns instead of all native columns.
  • Add DefaultPrepAndExpectedTestCaseGeneratedIdRowOrderIT reproducing the defect and proving the fix (default still reproduces it, opt-in fixes it, opt-in still catches genuine mismatches), using the existing IDENTITY_TABLE fixture; added that DDL to derby/mysql/postgresql/oracle so it runs on all 9 database profiles.
  • Documented sortOnFilteredColumnsOnly in Javadoc and a new site "Sort Mode" section, cross-linked from the row-ordering guidance in PrepAndExpectedTestCase.adoc, equality.adoc, and decorators.adoc.

Fixes #672
Closes #676

Test plan

  • ./mvnw clean test — 1935 unit tests pass
  • ./mvnw clean verify -Phsqldb-2-7 — 351 ITs pass
  • ./mvnw clean verify -Ph2-1-4 — 351 ITs pass
  • ./mvnw clean verify -Pderby-10-14 — 351 ITs pass
  • ./mvnw clean install site — no new Asciidoctor/Javadoc warnings
  • CI matrix across all 9 databases (mysql/postgresql/oracle/mssql/db2 not run locally this session — new IDENTITY_TABLE DDL for those 4 uses standard, well-known syntax but wasn't executed live)

🤖 Generated with Claude Code

https://claude.ai/code/session_01AebUvmVvD9HpqAxDnKEBqK

Summary by Sourcery

Add an opt-in mode to DefaultPrepAndExpectedTestCase to sort tables on filtered columns only, preventing false comparison failures when the first column is a generated/identity value, and document and test this behavior across supported databases.

New Features:

  • Introduce VerifyTableDefinition#sortOnFilteredColumnsOnly to control whether table comparison sorts on filtered columns only or all native columns.
  • Add integration tests and XML datasets demonstrating generated-ID row order behavior and the new sort-on-filtered-columns-only option.

Bug Fixes:

  • Fix false DbComparisonFailure results in DefaultPrepAndExpectedTestCase when tables have a generated/identity first column excluded from comparison, but sorting still used all native columns.

Enhancements:

  • Refine DefaultPrepAndExpectedTestCase#verifyData to support the new sort-on-filtered-columns-only behavior while preserving backward-compatible defaults.
  • Update release notes and documentation to describe the new sort mode and its impact on row ordering and identity columns.

Documentation:

  • Document the sortOnFilteredColumnsOnly option in Javadoc and Asciidoc, including guidance on row ordering and identity/generated columns.

Tests:

  • Add DefaultPrepAndExpectedTestCaseGeneratedIdRowOrderIT to validate default behavior, the new filtered-columns sort mode, and that genuine mismatches are still detected.
  • Extend database-specific SQL setup (derby, mysql, postgresql, oracle) with an IDENTITY_TABLE fixture used by the new integration test.

Summary by CodeRabbit

  • New Features

    • Added an opt-in setting to sort table comparisons using only included columns.
    • Improves reliability when generated or identity columns are excluded and rows are inserted in different orders.
    • Existing behavior remains unchanged by default.
  • Documentation

    • Added configuration guidance, sorting behavior details, and usage examples.
  • Tests

    • Added coverage for generated-ID row ordering, matching data, and genuine mismatches across supported databases.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@sourcery-ai

sourcery-ai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Reviewer's Guide

Introduce an opt-in sort-on-filtered-columns-only mode in DefaultPrepAndExpectedTestCase to fix false DbComparisonFailure mismatches on tables with generated/identity key columns, wire it through VerifyTableDefinition, add integration coverage using a new IDENTITY_TABLE fixture across multiple databases, and document the new behavior in code and site docs including the changelog.

Sequence diagram for sortOnFilteredColumnsOnly behavior in DefaultPrepAndExpectedTestCase.verifyData

sequenceDiagram
    actor Test
    participant VerifyTableDefinition
    participant DefaultPrepAndExpectedTestCase
    participant expectedTable as ITable_expected
    participant actualTable as ITable_actual
    participant SortedExpected as SortedTable_expected
    participant SortedActual as SortedTable_actual

    Test->>VerifyTableDefinition: setSortOnFilteredColumnsOnly(true|false)
    Test->>DefaultPrepAndExpectedTestCase: verifyData(connection, verifyTableDefinition)
    DefaultPrepAndExpectedTestCase->>DefaultPrepAndExpectedTestCase: loadTableDataFromDatabase(tableName, connection)
    DefaultPrepAndExpectedTestCase->>VerifyTableDefinition: isSortOnFilteredColumnsOnly()
    VerifyTableDefinition-->>DefaultPrepAndExpectedTestCase: sortOnFilteredColumnsOnly

    DefaultPrepAndExpectedTestCase->>DefaultPrepAndExpectedTestCase: makeExpectedTableColumns(actualTableColumns, expectedTableMetaData)

    alt [sortOnFilteredColumnsOnly true]
        DefaultPrepAndExpectedTestCase->>DefaultPrepAndExpectedTestCase: makeSortColumns(actualTableColumns, excludeColumns, includeColumns, tableName)
        DefaultPrepAndExpectedTestCase-->>DefaultPrepAndExpectedTestCase: actualSortColumns
        DefaultPrepAndExpectedTestCase->>DefaultPrepAndExpectedTestCase: makeSortColumns(expectedTableColumns, excludeColumns, includeColumns, tableName)
        DefaultPrepAndExpectedTestCase-->>DefaultPrepAndExpectedTestCase: expectedSortColumns
    else [sortOnFilteredColumnsOnly false]
        DefaultPrepAndExpectedTestCase-->>DefaultPrepAndExpectedTestCase: actualSortColumns = actualTableColumns
        DefaultPrepAndExpectedTestCase-->>DefaultPrepAndExpectedTestCase: expectedSortColumns = expectedTableColumns
    end

    DefaultPrepAndExpectedTestCase->>SortedExpected: new SortedTable(expectedTable, expectedSortColumns, true)
    DefaultPrepAndExpectedTestCase->>SortedActual: new SortedTable(actualTable, actualSortColumns)

    DefaultPrepAndExpectedTestCase->>DefaultPrepAndExpectedTestCase: assertion.verifyTables(SortedExpected, SortedActual, columnValueComparers)
Loading

File-Level Changes

Change Details Files
Add an overload of verifyData that can sort expected/actual tables using only columns that survive exclude/include filters, and route calls from DefaultPrepAndExpectedTestCase based on a new VerifyTableDefinition flag.
  • Add a boolean sortOnFilteredColumnsOnly parameter to a new verifyData overload and delegate the existing overload to it with default=false for backward compatibility.
  • Compute separate sort column arrays for expected and actual tables, either all native columns or filtered columns depending on sortOnFilteredColumnsOnly.
  • Introduce makeSortColumns helper that applies DefaultColumnFilter include/exclude semantics (including wildcards) to generate the sort key columns in original order.
src/main/java/org/dbunit/DefaultPrepAndExpectedTestCase.java
Expose configuration on VerifyTableDefinition to control whether tables are sorted by all native columns or by only filtered columns, defaulting to prior behavior.
  • Add sortOnFilteredColumnsOnly field with detailed Javadoc explaining when to enable it and its impact on generated/identity columns.
  • Implement isSortOnFilteredColumnsOnly and setSortOnFilteredColumnsOnly accessors with @SInCE tags and references to the field.
  • Keep verifyTableDefinitionVerifier and other existing configuration unchanged.
src/main/java/org/dbunit/VerifyTableDefinition.java
Extend database test fixtures with an IDENTITY_TABLE definition for multiple vendors to support generated-ID row-order tests.
  • Add DROP/CREATE DDL for IDENTITY_TABLE using vendor-appropriate identity/auto-increment syntax in mysql.sql, oracle.sql, postgresql.sql, and derby.sql.
  • Ensure IDENTITY_TABLE has an identity primary key as the first column plus two VARCHAR data columns to exercise the bug scenario.
  • Preserve existing tables and structure in each SQL file.
src/test/resources/sql/mysql.sql
src/test/resources/sql/oracle.sql
src/test/resources/sql/postgresql.sql
src/test/resources/sql/derby.sql
Document the new sort-on-filtered-columns-only behavior and changelog entry for the bug fix.
  • Update the 3.4.1-SNAPSHOT release description in changes.xml to include the new sort-on-filtered-columns-only mode and reference the generated/identity column bug fix.
  • Add/adjust Asciidoc site content (VerifyTableDefinition, equality, decorators, PrepAndExpectedTestCase) to describe the Sort Mode, how the new flag interacts with row ordering, and cross-links from relevant sections.
src/changes/changes.xml
src/site/asciidoc/components/verifytabledefinition.adoc
src/site/asciidoc/datacomparisons/equality.adoc
src/site/asciidoc/datasets/decorators.adoc
src/site/asciidoc/testcases/PrepAndExpectedTestCase.adoc
Add an integration test that reproduces the generated-ID row-order false failure, verifies the opt-in fix, and confirms genuine mismatches still fail, backed by new XML datasets.
  • Introduce DefaultPrepAndExpectedTestCaseGeneratedIdRowOrderIT that sets up IDENTITY_TABLE via DefaultPrepAndExpectedTestCase, configures VerifyTableDefinition with/without sortOnFilteredColumnsOnly, and asserts behavior using AssertJ.
  • Add XML datasets: prep with rows inserted in opposite order, expected match with data in canonical order, and expected mismatch with a deliberately wrong value.
  • Use excludeColumns to ignore the identity column while varying sortOnFilteredColumnsOnly to demonstrate defect reproduction, fix, and that mismatches remain detected.
src/test/java/org/dbunit/DefaultPrepAndExpectedTestCaseGeneratedIdRowOrderIT.java
src/test/resources/xml/generatedIdRowOrderExpectedMatch.xml
src/test/resources/xml/generatedIdRowOrderExpectedMismatch.xml
src/test/resources/xml/generatedIdRowOrderPrep.xml

Assessment against linked issues

Issue Objective Addressed Explanation
#672 Add an option in PrepAndExpectedTestCase to sort tables only on the filtered (exclude/include) columns instead of all native columns, to prevent random row-mismatch failures when excluded columns contain unpredictable values (e.g., generated IDs).
#672 Preserve backward compatibility by keeping the existing sort-on-all-columns behavior as the default, while allowing users to opt in to the new filtered-columns-only sort mode via configuration.
#676 Add a feature to PrepAndExpectedTestCase that allows toggling whether data is sorted for comparison on all columns or only on the filtered (exclude/include) columns.
#676 Preserve backward compatibility by keeping the default behavior as sorting on all columns.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jeffjensen, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 47 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a52a102d-10f7-4ffc-bb9e-a011b616c296

📥 Commits

Reviewing files that changed from the base of the PR and between d2ec29e and 51d35a3.

📒 Files selected for processing (18)
  • src/changes/changes.xml
  • src/main/java/org/dbunit/DefaultPrepAndExpectedTestCase.java
  • src/main/java/org/dbunit/VerifyTableDefinition.java
  • src/site/asciidoc/components/verifytabledefinition.adoc
  • src/site/asciidoc/datacomparisons/equality.adoc
  • src/site/asciidoc/datasets/decorators.adoc
  • src/site/asciidoc/testcases/PrepAndExpectedTestCase.adoc
  • src/test/java/org/dbunit/DefaultPrepAndExpectedTestCaseGeneratedIdRowOrderIT.java
  • src/test/java/org/dbunit/DefaultPrepAndExpectedTestCaseTest.java
  • src/test/java/org/dbunit/VerifyTableDefinitionTest.java
  • src/test/java/org/dbunit/dataset/AbstractDataSetTest.java
  • src/test/resources/sql/derby.sql
  • src/test/resources/sql/mysql.sql
  • src/test/resources/sql/oracle.sql
  • src/test/resources/sql/postgresql.sql
  • src/test/resources/xml/generatedIdRowOrderExpectedMatch.xml
  • src/test/resources/xml/generatedIdRowOrderExpectedMismatch.xml
  • src/test/resources/xml/generatedIdRowOrderPrep.xml
📝 Walkthrough

Walkthrough

VerifyTableDefinition now supports opt-in sorting on filtered columns. DefaultPrepAndExpectedTestCase applies the setting to expected and actual tables. Tests, identity-column fixtures, and documentation cover generated-column row ordering.

Changes

Filtered-column verification sorting

Layer / File(s) Summary
Verification option and sorting flow
src/main/java/org/dbunit/VerifyTableDefinition.java, src/main/java/org/dbunit/DefaultPrepAndExpectedTestCase.java
Adds sortOnFilteredColumnsOnly and applies filtered-column sorting when enabled. Existing all-column sorting remains the default.
Sorting behavior and configuration coverage
src/test/java/org/dbunit/DefaultPrepAndExpectedTestCaseTest.java, src/test/java/org/dbunit/VerifyTableDefinitionTest.java, src/test/java/org/dbunit/DefaultPrepAndExpectedTestCaseGeneratedIdRowOrderIT.java, src/test/resources/sql/*, src/test/resources/xml/generatedIdRowOrder*.xml, src/test/java/org/dbunit/dataset/AbstractDataSetTest.java
Tests constructor and setter configuration, default and filtered sorting, empty sort-column lists, mismatches, and generated identity-column row ordering across database fixtures.
Documentation and release notes
src/changes/changes.xml, src/site/asciidoc/components/verifytabledefinition.adoc, src/site/asciidoc/datacomparisons/equality.adoc, src/site/asciidoc/datasets/decorators.adoc, src/site/asciidoc/testcases/PrepAndExpectedTestCase.adoc
Documents the option, default behavior, configuration methods, and generated-column row-order scenarios.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant VerifyTableDefinition
  participant DefaultPrepAndExpectedTestCase
  participant DefaultColumnFilter
  VerifyTableDefinition->>DefaultPrepAndExpectedTestCase: provide sorting option
  DefaultPrepAndExpectedTestCase->>DefaultColumnFilter: apply include/exclude filters
  DefaultColumnFilter-->>DefaultPrepAndExpectedTestCase: return retained columns
  DefaultPrepAndExpectedTestCase->>DefaultPrepAndExpectedTestCase: sort expected and actual tables
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: fixing generated-ID row mismatches in PrepAndExpectedTestCase.
Linked Issues check ✅ Passed The implementation satisfies issues #672 and #676 by adding optional filtered-column sorting while preserving all-column sorting by default.
Out of Scope Changes check ✅ Passed The code, tests, database fixtures, and documentation directly support the linked issue objectives and regression coverage.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 672-prepandexpected-sort-filtered-columns

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The new makeSortColumns logic duplicates the column-filtering semantics in applyColumnFilters; consider refactoring to reuse a single implementation so that future changes to filter behavior stay consistent between sorting and comparison.
  • When sortOnFilteredColumnsOnly is true and all columns are excluded (or includeColumns yields an empty set), makeSortColumns will return an empty array—verify that SortedTable handles this as expected or add a guard to fall back to the full column set to avoid surprising behavior.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new makeSortColumns logic duplicates the column-filtering semantics in applyColumnFilters; consider refactoring to reuse a single implementation so that future changes to filter behavior stay consistent between sorting and comparison.
- When sortOnFilteredColumnsOnly is true and all columns are excluded (or includeColumns yields an empty set), makeSortColumns will return an empty array—verify that SortedTable handles this as expected or add a guard to fall back to the full column set to avoid surprising behavior.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/org/dbunit/DefaultPrepAndExpectedTestCase.java`:
- Around line 710-715: Update the verifyData invocation in
DefaultPrepAndExpectedTestCase so it preserves subclass overrides: call the
existing six-argument verifyData overload when sortOnFilteredColumnsOnly is
false, and call the new seven-argument overload only when it is true.

In `@src/site/asciidoc/components/verifytabledefinition.adoc`:
- Around line 95-97: Revise the default-behavior explanation near the
sort-by-all-columns setting to avoid claiming that non-generated or included
primary keys always sort correctly. State that the default is safe only when the
distinguishing sort columns are present in both tables, and that per-table
opt-in is required when such a column is excluded from the expected table.

In
`@src/test/java/org/dbunit/DefaultPrepAndExpectedTestCaseGeneratedIdRowOrderIT.java`:
- Around line 82-142: Add targeted unit tests in
DefaultPrepAndExpectedTestCaseTest covering
VerifyTableDefinition#setSortOnFilteredColumnsOnly(false) and true, and assert
that the resulting sort-key selection uses all columns by default and only
filtered columns when enabled. Reuse the existing test fixtures and verification
setup, keeping the tests focused on configuration behavior rather than database
integration.

In `@src/test/resources/sql/mysql.sql`:
- Around line 65-67: Update the IDENTITY_TABLE header comment to use valid MySQL
single-line comment syntax, ensuring each comment line begins with “--” followed
by whitespace while preserving the existing label and separator structure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e777387c-4320-4e41-80b1-feb4441471ef

📥 Commits

Reviewing files that changed from the base of the PR and between 171f1dd and 475f1e7.

📒 Files selected for processing (15)
  • src/changes/changes.xml
  • src/main/java/org/dbunit/DefaultPrepAndExpectedTestCase.java
  • src/main/java/org/dbunit/VerifyTableDefinition.java
  • src/site/asciidoc/components/verifytabledefinition.adoc
  • src/site/asciidoc/datacomparisons/equality.adoc
  • src/site/asciidoc/datasets/decorators.adoc
  • src/site/asciidoc/testcases/PrepAndExpectedTestCase.adoc
  • src/test/java/org/dbunit/DefaultPrepAndExpectedTestCaseGeneratedIdRowOrderIT.java
  • src/test/resources/sql/derby.sql
  • src/test/resources/sql/mysql.sql
  • src/test/resources/sql/oracle.sql
  • src/test/resources/sql/postgresql.sql
  • src/test/resources/xml/generatedIdRowOrderExpectedMatch.xml
  • src/test/resources/xml/generatedIdRowOrderExpectedMismatch.xml
  • src/test/resources/xml/generatedIdRowOrderPrep.xml

Comment thread src/main/java/org/dbunit/DefaultPrepAndExpectedTestCase.java Outdated
Comment thread src/site/asciidoc/components/verifytabledefinition.adoc Outdated
Comment thread src/test/resources/sql/mysql.sql
@jeffjensen

Copy link
Copy Markdown
Member Author

Addressing Sourcery's two points from the initial review:

  1. makeSortColumns duplicating applyColumnFilters — intentional, not accidental duplication. applyColumnFilters operates on ITable (returns a filtered ITable via DefaultColumnFilter.includedColumnsTable/excludedColumnsTable); makeSortColumns needs Column[] (what SortedTable's constructor takes), a different input/output shape SortedTable requires. Rather than reimplementing name-matching, makeSortColumns calls DefaultColumnFilter.accept() directly — the same underlying matcher (including wildcard pattern support) both applyColumnFilters call sites use internally — so the two stay semantically unified at that shared primitive instead of duplicating matching logic. Restructuring applyColumnFilters itself to share more than that would mean reshaping a working, tested method for a cosmetic gain; happy to revisit if that primitive drifts in practice.

  2. Empty sort-column array when everything is excluded — verified: SortedTable's comparator loop is for (i = 0; i < _sortColumns.length; i++), so a zero-length array just returns 0 immediately for every pair, i.e. Arrays.sort leaves rows in their original (stable) order — no exception. This is fine rather than surprising: the corresponding comparison (via the same exclude/include filters) also has zero columns to compare in that scenario, so row order doesn't matter for correctness either way. A "fall back to the full column set" guard would actually be wrong here — it would silently reintroduce this PR's own bug (sorting by an excluded generated column) for that edge case. Added testVerifyData_withSortOnFilteredColumnsOnlyTrueAndAllColumnsExcluded_doesNotThrow in 98cda0f to lock this in as a regression test rather than just leaving it as reasoning in a comment.

Also fixed CodeRabbit's four inline findings (replied individually on each thread) — one blocking (subclass override hook bypass), two docs/test-coverage suggestions applied, one (MySQL -- comment syntax) verified against DdlExecutor.readSqlFromFile()'s actual line-stripping behavior and declined as not applicable to how this project executes its test DDL.

@jeffjensen
jeffjensen force-pushed the 672-prepandexpected-sort-filtered-columns branch from 98cda0f to d2ec29e Compare August 4, 2026 11:56

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/test/java/org/dbunit/dataset/AbstractDataSetTest.java`:
- Around line 85-96: Update the JavaDoc for removeExtraTestTables to describe
the identity-column test tables as cross-database rather than MSSQL-specific,
and document that PostgreSQL folds unquoted identifiers to lowercase while other
vendors use uppercase. Keep the existing table-removal behavior unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 16aa04d9-3cc1-4f2a-9022-8832048b3e06

📥 Commits

Reviewing files that changed from the base of the PR and between 475f1e7 and d2ec29e.

📒 Files selected for processing (18)
  • src/changes/changes.xml
  • src/main/java/org/dbunit/DefaultPrepAndExpectedTestCase.java
  • src/main/java/org/dbunit/VerifyTableDefinition.java
  • src/site/asciidoc/components/verifytabledefinition.adoc
  • src/site/asciidoc/datacomparisons/equality.adoc
  • src/site/asciidoc/datasets/decorators.adoc
  • src/site/asciidoc/testcases/PrepAndExpectedTestCase.adoc
  • src/test/java/org/dbunit/DefaultPrepAndExpectedTestCaseGeneratedIdRowOrderIT.java
  • src/test/java/org/dbunit/DefaultPrepAndExpectedTestCaseTest.java
  • src/test/java/org/dbunit/VerifyTableDefinitionTest.java
  • src/test/java/org/dbunit/dataset/AbstractDataSetTest.java
  • src/test/resources/sql/derby.sql
  • src/test/resources/sql/mysql.sql
  • src/test/resources/sql/oracle.sql
  • src/test/resources/sql/postgresql.sql
  • src/test/resources/xml/generatedIdRowOrderExpectedMatch.xml
  • src/test/resources/xml/generatedIdRowOrderExpectedMismatch.xml
  • src/test/resources/xml/generatedIdRowOrderPrep.xml
🚧 Files skipped from review as they are similar to previous changes (13)
  • src/test/resources/sql/postgresql.sql
  • src/test/resources/sql/derby.sql
  • src/test/resources/sql/mysql.sql
  • src/test/resources/xml/generatedIdRowOrderExpectedMismatch.xml
  • src/test/resources/sql/oracle.sql
  • src/test/resources/xml/generatedIdRowOrderExpectedMatch.xml
  • src/site/asciidoc/datasets/decorators.adoc
  • src/test/resources/xml/generatedIdRowOrderPrep.xml
  • src/site/asciidoc/testcases/PrepAndExpectedTestCase.adoc
  • src/changes/changes.xml
  • src/site/asciidoc/datacomparisons/equality.adoc
  • src/test/java/org/dbunit/DefaultPrepAndExpectedTestCaseGeneratedIdRowOrderIT.java
  • src/main/java/org/dbunit/DefaultPrepAndExpectedTestCase.java

Comment thread src/test/java/org/dbunit/dataset/AbstractDataSetTest.java
The enhancement fixes DefaultPrepAndExpectedTestCase table comparison
row mismatches with situations such as generated-IDs.

DefaultPrepAndExpectedTestCase#verifyData always sorted the actual table
by all of its native columns - including a generated/identity first
column - while sorting the expected table by only the columns its file
declares, which typically omits that column since its value is unknown
ahead of time. excludeColumns/includeColumns were applied to the
comparison but never to the sort, so when production code does not
guarantee row insertion order (e.g. Hibernate reordering a batch
insert), the database's generated-ID assignment order diverges from the
data-content order the expected table sorts by, misaligning same-data
rows and failing the comparison despite both sides holding identical
data.

* Add VerifyTableDefinition#sortOnFilteredColumnsOnly (default false,
  preserving prior behavior), implementing the opt-in toggle proposed in
  issue 676: when true, both tables sort by only their
  excludeColumns/includeColumns-filtered columns instead of all native
  columns. verifyData(IDatabaseConnection, VerifyTableDefinition) only
  routes through the new seven-argument verifyData overload when the
  flag is true; it keeps calling the existing six-argument overload
  otherwise, so a subclass overriding that overload is still invoked in
  the (default) common case.
* Add DefaultPrepAndExpectedTestCaseGeneratedIdRowOrderIT reproducing
  the defect and proving the fix (default still reproduces it, opt-in
  fixes it, opt-in still catches genuine mismatches), using the existing
  IDENTITY_TABLE fixture. Add matching IDENTITY_TABLE DDL to derby.sql,
  mysql.sql, postgresql.sql, and oracle.sql (previously only in
  hypersonic.sql, h2.sql, mssql.sql, and db2xml.sql) so it runs on all 9
  database profiles; also add the table's lowercase form to
  AbstractDataSetTest's cross-vendor test-table exclusion list, since
  PostgreSQL - unlike the other vendors here - folds unquoted
  identifiers to lowercase.
* Add unit tests in DefaultPrepAndExpectedTestCaseTest exercising
  sortOnFilteredColumnsOnly true/false directly against mock tables (no
  database), including confirming an all-columns-excluded table sorts as
  a safe no-op instead of throwing.
* Document sortOnFilteredColumnsOnly in Javadoc and a new "Sort Mode"
  site section, cross-linked from PrepAndExpectedTestCase.adoc's
  row-ordering description and the general row-ordering guidance in
  equality.adoc/decorators.adoc.

Refs: 672
Refs: 676

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AebUvmVvD9HpqAxDnKEBqK
@jeffjensen
jeffjensen force-pushed the 672-prepandexpected-sort-filtered-columns branch from d2ec29e to 51d35a3 Compare August 4, 2026 12:08
@jeffjensen
jeffjensen merged commit 604bb2b into main Aug 4, 2026
27 checks passed
@jeffjensen
jeffjensen deleted the 672-prepandexpected-sort-filtered-columns branch August 4, 2026 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow PrepAndExpectedTestCase to sort only on filtered columns instead of all columns PrepAndExpectedTestCase should only sort on filtered columns

1 participant