Dataset Values
Overview
Dataset formats store field values as text — always for
Flat XML, XML, CSV,
JSON, and YAML; for Excel,
except where an .xls cell is natively a number, date, or boolean. dbUnit
turns each value into a typed column value with the column’s
DataType: DataType.typeCast() parses a string using
the SQL type dbUnit resolved for the column (from database metadata, a DTD, or
an explicit column declaration), and passes a value that is already the right
type straight through. Because the conversion is driven by the column’s type
rather than the file format, the rules on this page apply the same way
whichever format the value came from.
A handful of those rules are triggered by an extended syntax: when a string
value starts with [, the binary and date/time types treat the bracketed
prefix as an instruction rather than literal content
(DataType.isExtendedSyntax() — value starts with [). This is how
[TEXT|BASE64|FILE|URL] loads binary data and how [now…] produces a
relative date. String columns never do this — a leading [ is stored
verbatim.
The ReplacementDataSet decorator is a
separate mechanism: it swaps placeholder objects and substrings before
typeCast() sees them, and is the basis for the widely used [NULL]
convention below.
Null
Each format has its own way to say "this cell is null":
| Format | Null representation |
|---|---|
| Flat XML | Omit the attribute. A row that does not mention COL2 has a null COL2. |
| XML | An explicit <null/> or <none/> element in the row. |
| CSV | The literal token null, unquoted. A quoted "null" is the four-character string. |
| JSON | Omit the key from that row’s object. (Writing a dataset omits null-valued keys rather than emitting JSON null.) |
| YAML | Omit the key from that row’s mapping. |
| Excel | An empty or absent cell. |
Each format page states its own convention in its own words; the table above is a cross-reference, not a replacement.
The [NULL] placeholder
[NULL] is not built into the type layer — on a binary or numeric column it
is a TypeCastException, and on a string column it is stored literally as the
five characters [NULL]. It only means "null" when a
ReplacementDataSet is configured to
replace it:
ReplacementDataSet dataSet = new ReplacementDataSet(new FlatXmlDataSet(...));
dataSet.addReplacementObject("[NULL]", null);This is the standard way to express null in Flat XML when the first row of a
table would otherwise carry a null (which, without a DTD, would drop the
column from the table’s metadata). Add dataSet.setStrictReplacement(true) to
fail fast if a placeholder is left unreplaced instead of passing it through
silently. See ReplacementDataSet for
the full mechanics and Data File Loader for loaders that
apply replacements automatically.
Empty string vs. missing
A missing value is null (previous section). An explicitly empty string —
COL="" in Flat XML — is different: by default dbUnit rejects it on
INSERT/UPDATE rather than treating it as null or as an empty string.
table.column=TEST_TABLE.COL0 value is empty but must contain a value (to disable this feature check, set DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS to true)
The check (AbstractBatchOperation) fires only for a genuinely empty string
(""), not for null or a missing attribute. Set the
FEATURE_ALLOW_EMPTY_FIELDS feature
to true to let empty strings through to the database:
config.setFeature(DatabaseConfig.FEATURE_ALLOW_EMPTY_FIELDS, true);Binary, BLOB, and CLOB
dbUnit datasets are text, so binary columns (BINARY, VARBINARY,
LONGVARBINARY, BLOB) use an extended syntax to say how the text should
become bytes:
... COL0="[TEXT|BASE64|FILE|URL <optional argument>] optional text"
The command word is matched case-insensitively. Everything after the closing
] is the payload.
TEXT
Stores the text after ] as bytes. The default encoding is UTF-8; an optional
second word overrides it.
<!DOCTYPE dataset SYSTEM "my-dataset.dtd">
<dataset>
<TABLE_WITHBLOB COL0="[TEXT]This is my text, saved in UTF-8 (default) encoding. Java: bon café!"
COL1="row 0 col 1"
COL2="row 0 col 2"/>
</dataset><!DOCTYPE dataset SYSTEM "my-dataset.dtd">
<dataset>
<TABLE_WITHBLOB COL0="[TEXT ISO-8859-1]This is my text, saved in ISO-8859-1 encoding. Java: bon café!"
COL1="row 0 col 1"
COL2="row 0 col 2"/>
</dataset>An unknown encoding name is a TypeCastException.
BASE64
Decodes the Base64 text after ] into bytes.
<!DOCTYPE dataset SYSTEM "my-dataset.dtd">
<dataset>
<TABLE_WITHBLOB COL0="[BASE64]VGhpcyBpcyBteSB0ZXh0Lg=="
COL1="row 0 col 1"
COL2="row 0 col 2"/>
</dataset>FILE
Reads the bytes from a file. The path is the whole string after ] and may
contain spaces.
<!DOCTYPE dataset SYSTEM "my-dataset.dtd">
<dataset>
<TABLE_WITHBLOB COL0="[FILE]/path/to file to insert contents"
COL1="row 0 col 1"
COL2="row 0 col 2"/>
</dataset>URL
Reads the bytes from a URL.
<!DOCTYPE dataset SYSTEM "my-dataset.dtd">
<dataset>
<TABLE_WITHBLOB COL0="[URL]http://url%20here"
COL1="row 0 col 1"
COL2="row 0 col 2"/>
</dataset>A FILE or URL that cannot be read is a TypeCastException naming the
instruction.
Without the bracket syntax
A binary value with no […] prefix is resolved by guessing. A value of 1 to
256 characters is tried as a URL and then as a file path. An empty value, a
value longer than 256 characters, and any short value that is neither a
readable URL nor an existing file are Base64-decoded, falling back to raw
UTF-8 bytes when the text is not valid Base64. A value that is a well-formed
URL but cannot be fetched is a TypeCastException — it does not fall through
to the file or Base64 step.
A value whose […] prefix is not one of the four commands — [BOGUS]…, or
the [NULL] placeholder if it reaches a binary column without a
ReplacementDataSet — is a
TypeCastException naming the unrecognized command. A value that starts with
[ but has no closing ] is not command syntax and is resolved as a raw
value, as above.
CLOB columns are character data and follow the string rules, not this
section; [TEXT|BASE64|FILE|URL] is for binary types.
Dates and times
Literal formats
dbUnit uses the JDBC escape formats:
| Type | Format |
|---|---|
DATE |
yyyy-mm-dd |
TIME |
hh:mm:ss |
TIMESTAMP |
yyyy-mm-dd hh:mm:ss.fffffffff |
A TIMESTAMP value may carry a numeric timezone offset suffix such as
2024-03-01 12:00:00.0 +0100; see the MSSQL
guide for how TIMESTAMP WITH TIME ZONE columns are handled.
Relative dates — [now…]
Since 2.7.0, a DATE, TIME, or TIMESTAMP field can be written relative to
the current date/time:
... field_name="[now{diff...}{time}]"Each diff is a signed number followed by a unit character; multiple are
allowed, in any order, with optional whitespace around each. An optional
trailing time in HH:MM or HH:MM:SS form replaces the current time of day —
the syntax allows only digits and :, so no fractional seconds and no zone
offset. Both the offsets and the time are optional.
y: yearsM: monthsd: daysh: hoursm: minutess: seconds
Examples:
[now]— current date/time[now-1d]— the same time yesterday[now+1y+1M-2h]— a year and a month from today, two hours earlier[now+1d 10:00]— 10 o’clock tomorrow
An input that starts with [ but is not a valid [now…] expression is a
TypeCastException — there is no way to store a literal leading [ in a
date/time column (see Literal leading bracket).
UUIDs in binary columns
A BINARY/VARBINARY/LONGVARBINARY column (mapped by
UuidAwareBytesDataType) recognizes a
UUID literal, so UUIDs stored as raw bytes need not be Base64- or hex-encoded
by hand. Write the field as
uuid’xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' (hex, big-endian); it is stored
as the 16-byte encoding. The literal is matched anywhere in the value, so
anything around it is discarded — keep the field to just the literal.
<company id="uuid'791ae85a-d8d0-11e2-8c43-50e549c9b654'" name="ACME"/>This applies to BINARY-family columns only. A BLOB column
(BlobDataType) does not decode the literal — it would store the 42
characters of uuid'…' as text bytes.
Booleans and numbers from strings
Boolean columns (BOOLEAN, BIT): true and false are recognized
case-insensitively. Any other value is parsed as an integer, then 0 is
false and any non-zero is true. A value that is neither (yes, y, …)
is a TypeCastException.
Integer columns (TINYINT, SMALLINT, INTEGER): also accept true /
false (case-insensitive) as 1 / 0, otherwise parse the value as a
number.
Decimal columns (NUMERIC, DECIMAL): a Boolean value becomes 1 or
0, but the strings "true" / "false" are not special here — they are a
TypeCastException. Everything else goes through new BigDecimal(value).
In CSV, a numeric field with a trailing space before the comma is read as a string, not a number.
Token and placeholder replacement
dbUnit has no built-in templating in field values beyond what the sections
above describe. Arbitrary substitution is done by the
ReplacementDataSet /
ReplacementTable decorators, which replace whole placeholder objects and
substrings that you register:
ReplacementDataSet dataSet = new ReplacementDataSet(new FlatXmlDataSet(...));
dataSet.addReplacementObject("[NULL]", null);
dataSet.addReplacementSubstring("$USER", "scott");Injecting the current system time is a
worked example — register a java.util.Date object under a placeholder and it
is substituted before comparison or insert. Data File
Loader implementations wrap every dataset they load in a ReplacementDataSet
automatically.
Literal leading bracket
A value that starts with [ is only special for binary and date/time
columns:
| Column type | A value starting with [ |
|---|---|
| String / CLOB | Stored verbatim. [NULL], [foo], [TEXT]x are all literal text. |
DATE / TIME / TIMESTAMP |
Always parsed as a [now…] expression; anything else is a TypeCastException. No escape. |
| Binary / BLOB | Always parsed as [TEXT|BASE64|FILE|URL]; an unrecognized command is a TypeCastException (see Without the bracket syntax). No escape. |
There is no escape character for a leading [ on a binary or temporal column.
If a date/time or binary column must hold a value that would collide with the
extended syntax, substitute it in with a
ReplacementDataSet instead of writing
it in the file.
Column sensing (Flat XML)
Flat XML deduces a table’s columns from its first row. A later row with an attribute the first row lacked produces:
Extra columns on line x. Those columns will be ignored. Please add the extra columns to line 1, or use a DTD to make sure the value of those columns are populated.
Three ways to fix it:
- Declare every column on the first row (use
[NULL]or omit-for-null as needed). - Reference a DTD — dbUnit takes the table’s columns from it.
- Enable column sensing, which buffers the whole document and adds columns as they first appear:
FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
builder.setColumnSensing(true);
IDataSet dataSet = builder.build(new File("dataset.xml"));YAML and JSON do not have this problem — they take a table’s columns from the union of all its rows. CSV declares columns in a header row, so it is unaffected too.


