Skip to content
Jin Kwon edited this page Jul 6, 2026 · 2 revisions

Model Notes

MetadataType

All bound result classes implement MetadataType, which extends Serializable.

Map<String, Object> unknownColumns = value.getUnknownColumns();

getUnknownColumns() records result-set columns returned by a JDBC driver that do not have a mapped field in the model class. This is useful because drivers sometimes expose vendor-specific metadata columns or differ across versions.

Binding Behavior

Context binds rows by:

  • reading the result-set column labels;
  • finding fields annotated with the internal _ColumnLabel annotation;
  • assigning result values by label;
  • storing unmapped result-set columns in MetadataType.getUnknownColumns().

Mapped fields are exposed through typed getters such as Table.getTableName(), Column.getDataType(), and PrimaryKey.getKeySeq().

Column labels are matched in upper case. Binding first tries ResultSet.getObject(label) and direct field assignment. If the JDBC driver returns a value whose runtime type does not directly match the field type, the binder falls back to type-specific JDBC reads for Boolean, Short, Integer, and Long, then to ResultSet.getObject(label, fieldType).

Nullness

The package is annotated with JSpecify @NullMarked, and nullable JDBC values are explicitly marked in source with @Nullable.

Practical implications:

  • catalog and schema values may be null;
  • optional remarks, default values, generated-column flags, and driver-dependent metadata may be null;
  • JDBC integer and boolean values are exposed as wrapper types where a database or driver may report SQL NULL.
  • ported-key catalog, schema, and key-name accessors are nullable.

Validation Predicates

The current source tree contains plain protected predicate methods for several JDBC specification constraints. These are not Jakarta Bean Validation annotations and do not add a Bean Validation runtime dependency; tests call the predicates directly.

Current examples include:

Type Predicate coverage
Attribute REF scope fields and DISTINCT/REF source data type constraints
Column nullable-value enumeration, REF scope fields, and DISTINCT/REF source data type constraints
IndexInfo tableIndexStatistic rows requiring null index metadata, zero ordinal position, and non-unique false/null
VersionColumn pseudo-column value enumeration

Relationships

The source contains internal relationship annotations that document how metadata records relate to each other.

Parent Children
Catalog Table, Schema, Procedure, Function, UDT
Schema Table, Procedure, Function, UDT
Table VersionColumn, PseudoColumn, TablePrivilege, PrimaryKey, IndexInfo, ImportedKey, ExportedKey, CrossReference, SuperTable, Column, ColumnPrivilege, BestRowIdentifier
Procedure ProcedureColumn
Function FunctionColumn
UDT SuperType, Attribute

Some result types are explicitly marked as having no required parent context, including Catalog, Schema, Table, Procedure, Function, UDT, TableType, TypeInfo, and ClientInfoProperty.

Ordering

Most JDBC metadata methods define an expected order for their result sets. Context preserves the order returned by the JDBC driver. Some model classes also contain comparator helpers for ordering records in the specification's expected order when driver behavior needs to be checked or normalized.

The current source tree uses package-private comparingInSpecifiedOrder(...) factories on ordered model classes. Comparator helpers that compare nullable values use ContextUtils.withDatabaseNullOrdering(Context, Comparator, SortDirection) so null ordering follows the wrapped DatabaseMetaData instance. String comparison policy is supplied by the caller through a Comparator<? super String>; the library does not impose a collation or case-folding policy.

These comparators model the JDBC-specified comparison keys, not object identity. Distinct rows can compare equal when the specification does not order by every bound column, so they are appropriate for list sorting and test assertions, not as uniqueness comparators for TreeSet or TreeMap.

Known driver ordering and duplicate issues are tracked from the repository README:

  • MariaDB: table ordering, function ordering, and client-info property ordering issues are linked.
  • MySQL: duplicate table rows from DatabaseMetaData#getTables are linked.
  • PostgreSQL: duplicate function-column rows are linked.
  • SQL Server: procedure ordering issue is linked.

Context Utilities

ContextUtils is public for null-ordering comparator support and otherwise contains package-level binding helpers. Its public pieces are:

API Purpose
ContextUtils.SortDirection Describes ascending or descending order for null-ordering decisions.
ContextUtils.withDatabaseNullOrdering(context, comparator, direction) Wraps a comparator with nullsFirst or nullsLast according to DatabaseMetaData.nullsAreSortedAtStart, nullsAreSortedAtEnd, nullsAreSortedLow, and nullsAreSortedHigh.

Scope Of The Library

The library does not create schemas, introspect SQL text, or normalize database products into a single metadata dialect. It keeps JDBC metadata visible as typed Java records while preserving JDBC driver behavior.

Clone this wiki locally