From 4674c5d8356fce24eda0618c31bf9e71613ceb58 Mon Sep 17 00:00:00 2001 From: Jeff Jensen Date: Wed, 19 Aug 2026 21:33:54 -0500 Subject: [PATCH 1/3] fix(dataset): Restrict FlatXmlProducer empty-table backfill to DTD metadata Issue #496's fix made FlatXmlProducer#addMissingDtdTables() backfill every table name reported by any metaDataSet as an empty table, not just DTD-derived metadata. FlatXmlDataSetBuilder#setMetaDataSet(IDataSet) accepts an arbitrary IDataSet supplied purely for column-type lookups (e.g. a live database's full IDataSet), and that dataset's table list is not an enumeration of the fixture; treating it as one pulled every table from the broader source into the produced dataset, so DELETE_ALL/CLEAN_INSERT touched tables the flat XML never mentioned. * Only run the backfill when _metaDataSet is a FlatDtdDataSet, i.e. DTD-derived (inline-parsed DOCTYPE, or explicitly supplied via FlatXmlDataSetBuilder#setMetaDataSetFromDtd). An arbitrary metadata IDataSet no longer contributes tables absent from the XML body, restoring pre-3.5.0 behavior for that case. * Rework the existing non-DTD backfill test to instead prove tables are NOT added for an arbitrary metaDataSet, and add a new test proving a FlatDtdDataSet supplied directly (mirroring setMetaDataSetFromDtd) still gets the #496 backfill. Refs: 951 Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_015sHWqvYLtLwtzAGVunuWLa --- src/changes/changes.xml | 5 ++ .../dbunit/dataset/xml/FlatXmlProducer.java | 19 +++--- src/site/asciidoc/index.adoc | 16 ++--- .../dataset/xml/FlatXmlProducerTest.java | 60 +++++++++++++++++-- 4 files changed, 78 insertions(+), 22 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index f1c8dd2ef..c9dd114f3 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -13,6 +13,11 @@ + + + Fix a 3.5.0 regression (introduced by issue #496's fix) where FlatXmlProducer added every table from an explicitly-supplied metadata IDataSet as an empty table, not just tables actually present in the flat XML body: FlatXmlDataSetBuilder#setMetaDataSet(IDataSet) is documented as supplying column metadata only, but a broad metadata source such as a live database's full IDataSet (e.g. via DatabaseConnection#createDataSet()) was being read as if it enumerated the fixture's own tables, so DELETE_ALL/CLEAN_INSERT ended up touching every table in that broader source instead of only the ones the XML body mentions. FlatXmlProducer's issue #496 empty-table backfill now only runs when the metadata source is DTD-derived (a FlatDtdDataSet, whether parsed inline from the flat XML's own DOCTYPE or supplied via FlatXmlDataSetBuilder#setMetaDataSetFromDtd), restoring pre-3.5.0 behavior for any other explicitly-supplied metadata dataset. + + Add repo-root README.adoc, rendered natively by GitHub via Asciidoctor, so the repository landing page shows a pitch, build/reproducible-build badges, a pointer to the "dbUnit in 5 Minutes" tutorial, and links to the documentation site, Maven coordinates, GitHub Discussions, and CONTRIBUTING.md instead of nothing. diff --git a/src/main/java/org/dbunit/dataset/xml/FlatXmlProducer.java b/src/main/java/org/dbunit/dataset/xml/FlatXmlProducer.java index 6ac03b576..31d530ee6 100644 --- a/src/main/java/org/dbunit/dataset/xml/FlatXmlProducer.java +++ b/src/main/java/org/dbunit/dataset/xml/FlatXmlProducer.java @@ -333,19 +333,22 @@ private boolean isNewTable(String tableName) } /** - * Notifies the consumer of every table declared in {@link #_metaDataSet} (DTD or - * explicit metadata dataset) that never appeared as a row element in the XML body, - * as an empty table using that source's column metadata. Without this, a table with - * zero rows in a given fixture is silently absent from the produced dataset, which - * can make operations like {@code CLEAN_INSERT}/{@code DELETE_ALL} skip it entirely - * even though the DTD declares it. No-op when no DTD/metadata dataset is available, - * so behavior is unchanged for plain flat XML. + * Notifies the consumer of every table declared in a DTD-derived {@link #_metaDataSet} + * that never appeared as a row element in the XML body, as an empty table using that + * source's column metadata. Without this, a table with zero rows in a given fixture is + * silently absent from the produced dataset, which can make operations like + * {@code CLEAN_INSERT}/{@code DELETE_ALL} skip it entirely even though the DTD declares + * it. No-op when {@link #_metaDataSet} is not a {@link FlatDtdDataSet}, i.e. when there + * is plain flat XML or an arbitrary metadata {@link IDataSet} supplied via + * {@link FlatXmlDataSetBuilder#setMetaDataSet}: such a dataset is consulted only for + * column metadata of tables actually present in the XML body, not as an enumeration of + * every table the produced dataset should contain. * * @throws DataSetException if the consumer cannot be notified. */ private void addMissingDtdTables() throws DataSetException { - if (_metaDataSet == null) + if (!(_metaDataSet instanceof FlatDtdDataSet)) { return; } diff --git a/src/site/asciidoc/index.adoc b/src/site/asciidoc/index.adoc index 6adf6db04..2c4072207 100644 --- a/src/site/asciidoc/index.adoc +++ b/src/site/asciidoc/index.adoc @@ -46,14 +46,14 @@ We will gladly help you as needed with your ideas and contributions and look to |=== |Date |News -// |TBD -// |Please try the 3.5.0-SNAPSHOT snapshot build and let us know how it works! -// It adds `DbUnitExtension` for *native JUnit 5/6 lifecycle management*, a new *JSON dataset format* and JSON `ValueComparer`, *MariaDB and H2 2.x* database support, expanded PostgreSQL `json`/`jsonb` and array type support, and an opt-in escape hatch for *circular foreign keys*, plus a ground-up *documentation site overhaul* and numerous other bug fixes. -// See link:https://dbunit.github.io/dbunit-extension/repos.html#snapshots[SNAPSHOTS] for how to use them. -// Refer to the link:changes.html#a3.5.0-SNAPSHOT[changes report], -// the link:https://github.com/dbunit/dbunit-extension/issues?q=is%3Aissue+milestone%3A3.5.0%20type%3AFeature[feature list], and -// the link:https://github.com/dbunit/dbunit-extension/issues?q=is%3Aissue+milestone%3A3.5.0%20type%3ABug[bug list] -// for the snapshot contents (and subsequent updates). +|TBD +|Please try the 3.5.1-SNAPSHOT snapshot build and let us know how it works! +It fixes a 3.5.0 regression where `FlatXmlDataSetBuilder.setMetaDataSet()` pulled *every table in the supplied metadata source* into the produced dataset, not just the ones in the flat XML body. +See link:https://dbunit.github.io/dbunit-extension/repos.html#snapshots[SNAPSHOTS] for how to use them. +Refer to the link:changes.html#a3.5.1-SNAPSHOT[changes report], +the link:https://github.com/dbunit/dbunit-extension/issues?q=is%3Aissue+milestone%3A3.5.1%20type%3AFeature[feature list], and +the link:https://github.com/dbunit/dbunit-extension/issues?q=is%3Aissue+milestone%3A3.5.1%20type%3ABug[bug list] +for the snapshot contents (and subsequent updates). |2026-08-11 |Release 3.5.0 available. diff --git a/src/test/java/org/dbunit/dataset/xml/FlatXmlProducerTest.java b/src/test/java/org/dbunit/dataset/xml/FlatXmlProducerTest.java index 44bfd086d..170583595 100644 --- a/src/test/java/org/dbunit/dataset/xml/FlatXmlProducerTest.java +++ b/src/test/java/org/dbunit/dataset/xml/FlatXmlProducerTest.java @@ -159,7 +159,8 @@ void testProduceMetaDataSet_withMetaDataSetProvided_usesMetaDataSetColumnsForEmp } @Test - void testProduceMetaDataSet_withTableAbsentFromXmlBody_addsEmptyTableFromMetaDataSet() throws Exception + void testProduceMetaDataSet_withNonDtdMetaDataSetAndTableAbsentFromXmlBody_doesNotAddMissingTable() + throws Exception { // Setup consumer final String presentTable = "PRESENT_TABLE"; @@ -175,11 +176,12 @@ void testProduceMetaDataSet_withTableAbsentFromXmlBody_addsEmptyTableFromMetaDat final MockDataSetConsumer consumer = new MockDataSetConsumer(); consumer.addExpectedStartDataSet(); consumer.addExpectedEmptyTable(presentTable, presentColumns); - // MISSING_TABLE is declared in the supplied metaDataSet but never appears as a - // row element in the XML body; it must still be reported, with zero rows and its - // own column metadata, or a CLEAN_INSERT/DELETE_ALL relying on the produced - // dataset's table list would silently skip it (issue #496). - consumer.addExpectedEmptyTable(missingTable, missingColumns); + // MISSING_TABLE is declared in the supplied metaDataSet but never appears as a row + // element in the XML body. Unlike DTD-derived metadata, an arbitrary metaDataSet + // (e.g. a live database's full IDataSet, supplied only to resolve column info) is + // not an enumeration of the fixture's tables, so it must NOT be added: doing so + // previously made DELETE_ALL/CLEAN_INSERT touch every table in that broader source, + // not just the ones the XML body actually mentions (issue #951 regression from #496). consumer.addExpectedEndDataSet(); // Setup producer @@ -199,6 +201,52 @@ void testProduceMetaDataSet_withTableAbsentFromXmlBody_addsEmptyTableFromMetaDat consumer.verify(); } + @Test + void testProduceMetaDataSet_withFlatDtdDataSetAndTableAbsentFromXmlBody_addsEmptyTableFromMetaDataSet() + throws Exception + { + // Setup consumer + final String presentTable = "PRESENT_TABLE"; + final String missingTable = "MISSING_TABLE"; + // Deliberately different shapes (name and column count) per table, so a producer + // bug that mixed up which table's metadata to use would make this test fail + // instead of passing by coincidence. + final Column[] presentColumns = new Column[] { + new Column("PRESENT_COL", DataType.UNKNOWN, Column.NULLABLE)}; + final Column[] missingColumns = new Column[] { + new Column("MISSING_COL0", DataType.UNKNOWN, Column.NULLABLE), + new Column("MISSING_COL1", DataType.UNKNOWN, Column.NULLABLE)}; + final MockDataSetConsumer consumer = new MockDataSetConsumer(); + consumer.addExpectedStartDataSet(); + consumer.addExpectedEmptyTable(presentTable, presentColumns); + // MISSING_TABLE is declared in the DTD-derived metaDataSet but never appears as a + // row element in the XML body; it must still be reported, with zero rows and its + // own column metadata, or a CLEAN_INSERT/DELETE_ALL relying on the produced + // dataset's table list would silently skip it (issue #496). This mirrors what + // FlatXmlDataSetBuilder#setMetaDataSetFromDtd builds internally, so that path must + // keep the #496 backfill even though it is not the inline-parsed-DTD case. + consumer.addExpectedEmptyTable(missingTable, missingColumns); + consumer.addExpectedEndDataSet(); + + // Setup producer + final String content = "" + + "" + "" + + "" + ""; + final InputSource source = new InputSource(new StringReader(content)); + final String dtdContent = "" + + "" + + ""; + final FlatDtdDataSet metaDataSet = + new FlatDtdDataSet(new StringReader(dtdContent)); + final IDataSetProducer producer = + new FlatXmlProducer(source, metaDataSet); + producer.setConsumer(consumer); + + // Produce and verify consumer + producer.produce(); + consumer.verify(); + } + @Test void testProduceCustomEntityResolver_withCustomEntityResolver_usesResolverToLoadDtd() throws Exception { From 2c76618e5f3445a980e5b7663c3d835784c1c0a5 Mon Sep 17 00:00:00 2001 From: Jeff Jensen Date: Thu, 20 Aug 2026 07:44:58 -0500 Subject: [PATCH 2/3] chore(release): Prep 3.5.1 --- pom.xml | 33 ++++++++++++++++++++++++++++++--- src/changes/changes.xml | 2 +- src/site/site.xml | 1 + 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index d772728ff..c6ba065ce 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.dbunit dbunit - 3.5.1-SNAPSHOT + 3.5.1 jar dbUnit Extension https://github.com/dbunit/dbunit-extension @@ -23,7 +23,7 @@ - 2026-08-12T02:19:02Z + 2026-08-20T13:48:02Z UTF-8 UTF-8 github @@ -154,7 +154,7 @@ scm:git:https://github.com/dbunit/dbunit-extension.git scm:git:https://github.com/dbunit/dbunit-extension.git https://github.com/dbunit/dbunit-extension.git - dbunit-3.5.0 + dbunit-3.5.1 github @@ -1175,6 +1175,33 @@ --> + + 3.5.0-to-3.5.1 + + cmp-report + + + + 3.5.0-to-3.5.1 + + + + ${project.groupId} + ${project.artifactId} + 3.5.0 + jar + + + + + ${project.groupId} + ${project.artifactId} + 3.5.1 + jar + + + + 3.4.0-to-3.5.0 diff --git a/src/changes/changes.xml b/src/changes/changes.xml index c9dd114f3..df373ad62 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -13,7 +13,7 @@ - + Fix a 3.5.0 regression (introduced by issue #496's fix) where FlatXmlProducer added every table from an explicitly-supplied metadata IDataSet as an empty table, not just tables actually present in the flat XML body: FlatXmlDataSetBuilder#setMetaDataSet(IDataSet) is documented as supplying column metadata only, but a broad metadata source such as a live database's full IDataSet (e.g. via DatabaseConnection#createDataSet()) was being read as if it enumerated the fixture's own tables, so DELETE_ALL/CLEAN_INSERT ended up touching every table in that broader source instead of only the ones the XML body mentions. FlatXmlProducer's issue #496 empty-table backfill now only runs when the metadata source is DTD-derived (a FlatDtdDataSet, whether parsed inline from the flat XML's own DOCTYPE or supplied via FlatXmlDataSetBuilder#setMetaDataSetFromDtd), restoring pre-3.5.0 behavior for any other explicitly-supplied metadata dataset. diff --git a/src/site/site.xml b/src/site/site.xml index f7ce2f072..404069083 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -127,6 +127,7 @@ + From a1f59440bdadbb3edb7de98064bb03b49d6cacd3 Mon Sep 17 00:00:00 2001 From: Jeff Jensen Date: Thu, 20 Aug 2026 08:49:14 -0500 Subject: [PATCH 3/3] docs(site): Update index.adoc with 3.5.1 release --- src/site/asciidoc/index.adoc | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/site/asciidoc/index.adoc b/src/site/asciidoc/index.adoc index 2c4072207..8cd600ff5 100644 --- a/src/site/asciidoc/index.adoc +++ b/src/site/asciidoc/index.adoc @@ -46,14 +46,22 @@ We will gladly help you as needed with your ideas and contributions and look to |=== |Date |News -|TBD -|Please try the 3.5.1-SNAPSHOT snapshot build and let us know how it works! -It fixes a 3.5.0 regression where `FlatXmlDataSetBuilder.setMetaDataSet()` pulled *every table in the supplied metadata source* into the produced dataset, not just the ones in the flat XML body. -See link:https://dbunit.github.io/dbunit-extension/repos.html#snapshots[SNAPSHOTS] for how to use them. -Refer to the link:changes.html#a3.5.1-SNAPSHOT[changes report], +// |TBD +// |Please try the 3.5.1-SNAPSHOT snapshot build and let us know how it works! +// It fixes a 3.5.0 regression where `FlatXmlDataSetBuilder.setMetaDataSet()` pulled *every table in the supplied metadata source* into the produced dataset, not just the ones in the flat XML body. +// See link:https://dbunit.github.io/dbunit-extension/repos.html#snapshots[SNAPSHOTS] for how to use them. +// Refer to the link:changes.html#a3.5.1-SNAPSHOT[changes report], +// the link:https://github.com/dbunit/dbunit-extension/issues?q=is%3Aissue+milestone%3A3.5.1%20type%3AFeature[feature list], and +// the link:https://github.com/dbunit/dbunit-extension/issues?q=is%3Aissue+milestone%3A3.5.1%20type%3ABug[bug list] +// for the snapshot contents (and subsequent updates). + +|2026-08-20 +|Release 3.5.1 available. +It fixes a 3.5.1 regression where `FlatXmlDataSetBuilder.setMetaDataSet()` pulled *every table in the supplied metadata source* into the produced dataset, not just the ones in the flat XML body. +Refer to the link:changes.html#a3.5.1[changes report], the link:https://github.com/dbunit/dbunit-extension/issues?q=is%3Aissue+milestone%3A3.5.1%20type%3AFeature[feature list], and the link:https://github.com/dbunit/dbunit-extension/issues?q=is%3Aissue+milestone%3A3.5.1%20type%3ABug[bug list] -for the snapshot contents (and subsequent updates). +for the release contents. |2026-08-11 |Release 3.5.0 available.