Skip to content

Result Mapping

Result mapping converts JDBC result rows into the Java return type of a JDBC method. One row is converted into one Java value, such as a class, record, enum, or primitive value. If the method expects multiple rows, each row is converted and collected into the declared collection or array result.

Converter lookup is based on the Java result type. JDBC-to-Java converter lookup, exact type lookup, and dependency context are described in converter lookup. If no explicit converter is selected, result mapping can create default converters for supported enum, class, and record shapes. The sections below define the supported result-mapping forms used during lookup.

Java names are mapped to JDBC names as follows:

  • if the element is annotated with @JdbcName, the provided non-blank name is used
  • otherwise, camel-case names are converted to snake-case names

Result nullness follows the Nullness Contract. Optional<T> return forms are described by the JDBC method kind that uses result mapping.

A column Java type is created from one JDBC column. Primitive types, JDBC basic types, Java enums, and single-value converter results are column Java types. Records and classes can also be column Java types when their default converter uses exactly one component or constructor parameter.

A row-related Java type is created from a whole JDBC row. Records and classes are row-related Java types when their components or constructor parameters are mapped from multiple columns. Row converters that take a ResultSet also create row-related Java types.

❗️JDBC Types ❗️JDBC Additional Types ❗️Test with H2 driver

All JDBC basic types are column Java types.

  • The following JDBC Java types are mapped by default to the ResultSet.get... methods:
    • java.lang.String, java.math.BigDecimal, boolean, byte, short, int, long, float, double, byte[], java.sql.Date, java.sql.Time, java.sql.Timestamp, java.sql.Clob, java.sql.Blob, java.sql.Array, java.sql.Ref, java.net.URL, java.sql.RowId, java.sql.NClob, java.sql.SQLXML
    • java.sql.Struct (via getObject)
  • In addition, the following types are supported by default converters that map to the underlying ResultSet method:
    • java.lang.Boolean, java.lang.Byte, java.lang.Short, java.lang.Integer, java.lang.Long, java.lang.Float, java.lang.Double
    • char, java.lang.Character (via getString)
  • Some JDBC drivers do not support all types. Check your driver’s documentation.
❗️JDBC Types ❗️JDBC Types

Default converters are considered only after converter lookup does not find a matching explicit converter. For the exact lookup order, see converter lookup.

  • Java record: by default, JDBC columns are mapped to the record components. These Java records are generally row-related Java types. A Java record is a column Java type if all of these conditions match:
    • the record has exactly one component
    • the component is a column Java type
    • the component has no @JdbcName annotation
  • Java class: by constructor, if exactly one usable non-default constructor is available. These Java classes are generally row-related Java types. A Java class is a column Java type if all of these conditions match:
    • the constructor has exactly one parameter
    • the parameter is a column Java type
    • the parameter has no @JdbcName annotation
  • Java enum: by the enum name. It is a column Java type.
❗️io.kaumei.jdbc.spec.jdbc2java.ColumnTypeNameSpecTest ❗️io.kaumei.jdbc.spec.jdbc2java.ColumnFromObjectSpecTest ❗️io.kaumei.jdbc.spec.jdbc2java.ColumnResultSetSpecTest

The developer can define a column converter to convert a JDBC column into a column Java type. Column converters either receive the already-read column value or read the column directly from the ResultSet.

  • A static converter which converts a JDBC basic value T into a supported Java value R:
    • shape: static R toJava(T value)
    • The method must be annotated with @JdbcToJava
    • Parameter and return type must be unspecified or non-null.
    • The method will never be called with null and must never return null.
    • @JdbcName is not supported on the single value parameter.
    • Checked exceptions must be compatible with the JDBC method that uses the converter.
  • A static converter which gets a value R from a given ResultSet and an int index:
    • shape: static R columnToJava(ResultSet rs, int columnIndex) throws SQLException
    • The method must be annotated with @JdbcToJava
    • Parameter ResultSet rs must be non-null or unspecified.
    • The second parameter must be int.
    • Return must be unspecified or nullable.
    • Optional<T> is not supported as the return type.
    • The method must handle null correctly.
    • @JdbcName is not supported on the ResultSet parameter.
    • Checked exceptions must be compatible with the JDBC method that uses the converter.
❗️io.kaumei.jdbc.spec.jdbc2java.RowFromObjectsSpecTest ❗️io.kaumei.jdbc.spec.jdbc2java.RowFromResultSetSpecTest

The developer can define a row converter to convert a JDBC row into a row Java type. Row converters either receive the already-mapped column values or read the whole row directly from the ResultSet.

  • A static converter with column Java type parameters:
    • The method must be annotated with @JdbcToJava
    • Parameters must all be column Java types.
    • Parameter annotations @JdbcName are allowed.
    • Parameters may be unspecified, non-null, or nullable.
    • Optional<T> is not supported as a parameter type.
    • Return must be unspecified or non-null.
    • Checked exceptions must be compatible with the JDBC method that uses the converter.
    • The method must handle null correctly.
  • A static converter which gets a row value R from a given ResultSet and converts it into a row Java type:
    • shape: static R rowToJava(ResultSet rs) throws SQLException
    • The method must be annotated with @JdbcToJava
    • The method must have exactly one parameter.
    • Parameter ResultSet rs must be non-null or unspecified.
    • @JdbcName is not supported on the ResultSet parameter.
    • Return must be unspecified or non-null.
    • Checked exceptions must be compatible with the JDBC method that uses the converter.
    • The method must handle null correctly.