PostgreSQL

Overview

org.dbunit.ext.postgresql provides PostgreSQL-specific type recognition for dbUnit, covering several PostgreSQL types with no standard JDBC equivalent.

IDataTypeFactory

PostgresqlDataTypeFactory recognizes uuid, interval, inet, geometry, citext, json, jsonb, oid when reported as JDBC BIGINT, any array column (JDBC ARRAY, e.g. integer[], text[]), and (via an overridable hook) custom enum types, mapping each to the dedicated classes below; everything else delegates to DefaultDataTypeFactory. Register it via DatabaseConfig.PROPERTY_DATATYPE_FACTORY — see Properties and Connections & Configuration.

IMetadataHandler

Not overridden — the default handler applies.

Connection Preconfiguration Class

None — PostgreSQL has no dedicated IDatabaseConnection subclass. Register PostgresqlDataTypeFactory directly on a plain DatabaseConnection’s `DatabaseConfig:

IDatabaseConnection connection = new DatabaseConnection(jdbcConnection, schema);
connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
        new PostgresqlDataTypeFactory());

Vendor-Specific Types

Type Covers
PostgreSQLOidDataType Large objects (oid), read/written via the driver’s large-object API.
CitextType Case-insensitive text (citext).
IntervalType interval values.
InetType inet (IP address/network) values.
UuidType uuid values.
GeometryType geometry (PostGIS) values, read/written as their string representation.
JsonType json and jsonb values, read/written as their raw text representation.
ArrayType Array columns (e.g. integer[], text[]), read/written as their PostgreSQL literal text representation.

PostgreSQLOidDataType

PostgreSQLOidDataType reads and writes oid columns through the PostgreSQL JDBC driver’s large-object API (LargeObjectManager). Writing always creates a new large object and binds its oid; reading opens the large object the column’s oid refers to and returns its bytes, or null when the oid is zero (dbUnit’s convention for a SQL NULL in this column).

A PostgreSQL oid column is a generic object identifier, not necessarily a large object reference — see the PostgreSQL oid type documentation. A column holding some other catalog object’s oid (for example a table’s own oid via 'sometable'::regclass) now reads as null instead of failing the whole read: PostgreSQL reports this specific case as SQLState 42704 (undefined_object), which is distinguished from every other failure — a real access/permission error still propagates as an exception rather than being swallowed. Opening the large object runs under a savepoint, since PostgreSQL aborts the entire enclosing transaction on any failed command; rolling back to the savepoint on failure clears the abort without discarding any other work already done in that transaction, so the connection stays usable for the rest of the read.

GenericEnumType

GenericEnumType adapts between PostgreSQL’s native enum types and Strings, using reflection (PGobject.setType()) so dbUnit doesn’t need a compile-time dependency on the PostgreSQL driver’s internal types. PostgreSQL reports a custom enum type generically, so PostgresqlDataTypeFactory cannot recognize one on its own — override isEnumType(String sqlTypeName):

PostgresqlDataTypeFactory factory = new PostgresqlDataTypeFactory() {
    public boolean isEnumType(String sqlTypeName) {
        return "abc_enum".equalsIgnoreCase(sqlTypeName);
    }
};

See the FAQ for more: Are Postgresql enum types supported by dbunit?

Caution: isEnumType() is currently unreachable for an ordinary table column — see Known Quirks below.

JsonType

JsonType adapts between PostgreSQL’s native json/jsonb types and Strings, using the same reflection-based PGobject.setType() approach as the other types above. PostgreSQL has no implicit cast between json and jsonb, so a bound parameter’s PGobject type must match its target column exactly; PostgresqlDataTypeFactory handles this automatically by constructing a JsonType for the specific sql type name (json or jsonb) each column reports.

This class only shuttles a column’s raw text between the driver and the dataset; it does not compare JSON values semantically. PostgreSQL reformats jsonb text on storage (for example, inserting whitespace or reordering object keys), so a literal string comparison against an expected dataset value can spuriously fail even when the JSON is semantically identical. Use IsActualEqualToExpectedJsonValueComparer (see Value Comparers) to compare json/jsonb column values by their parsed document structure instead.

ArrayType

ArrayType adapts between PostgreSQL array columns and their PostgreSQL literal text representation, such as {1,2,3} or {"a","b","c"}. PostgreSQL reports every array column’s sql type name as its element type’s own pg_catalog name prefixed with an underscore (for example _int4 for an integer[] column); PostgresqlDataTypeFactory constructs the matching ArrayType for each column automatically.

On write, the literal text is split into its top-level elements — honoring double-quoted, backslash-escaped elements and the unquoted NULL keyword — and bound via Connection.createArrayOf(String, Object[]), letting PostgreSQL itself parse and validate each element against the column’s actual base type; dbUnit does not typecast elements to their Java equivalents itself. Only single-dimension arrays are supported for writing; a literal containing a nested array (a multi-dimensional array) is rejected. Reading one back for comparison or export works fine either way, since the literal text is never parsed on read.

Known Quirks

Enum type support requires the isEnumType() override above — see GenericEnumType. Currently, that override is never actually consulted for an ordinary table column: PostgreSQL’s JDBC driver reports a custom enum column’s JDBC type as VARCHAR (not OTHER) via DatabaseMetaData.getColumns(), the metadata source CLEAN_INSERT and IDatabaseConnection.createDataSet() use, so PostgresqlDataTypeFactory resolves the column as a plain string instead of GenericEnumType and an insert of a real value fails with a "column is of type …​ but expression is of type character varying" error — unrelated to and unaffected by null handling. Tracked as issue #933.

json/jsonb column comparisons in assertions are literal string comparisons unless you use IsActualEqualToExpectedJsonValueComparer — see JsonType above.

Array column comparisons in assertions are literal string comparisons against PostgreSQL’s own canonical output format (no extra whitespace, elements quoted only where required) — see ArrayType above. Writing a multi-dimensional array from a literal string is not supported; reading one back for comparison or export works fine.

An oid column reads as null both for a genuine SQL NULL and for an oid that doesn’t reference a large object — see PostgreSQLOidDataType above. dbUnit cannot distinguish the two cases from the read value alone, since neither has any large-object content to return.