Skip to content

✅ Converter lookup

Kaumei JDBC selects converters during parameter binding and result mapping. Converter preparation and resolution happen before code generation; generated code uses the converters prepared for the processed JDBC method and does not discover additional converters.

Converters are discovered only from reachable places:

  • built-in converters belong to the basic scope
  • converters declared directly in a JDBC interface belong to that interface’s local scope
  • converters declared in the selected @JdbcConfig type belong to the global scope
  • converters referenced by @JdbcConfig(converter = ...) belong to the global scope
  • converters found by inspecting a used Java type belong to the global scope

Used Java types come from JDBC method parameters, JDBC method return types, and nested converter dependencies needed for those parameters or return types. Converter definitions may be named or unnamed. Named converters are selected only by their names with @JdbcConverterName; type lookup does not fall back to a named converter.

Annotated converter methods or constructors outside the reachable paths are ignored. When used-type inspection finds an unnamed converter method or constructor, that converter is discovered through the used type and belongs to the global scope. Every discovered converter belongs to exactly one scope.

For a JDBC interface, scopes are searched in this order:

  1. local scope of the JDBC interface
  2. global scope
  3. basic scope

For name lookup and exact type lookup, the first matching converter wins. Java-to-JDBC hierarchy lookup has an additional specificity rule: a converter for a more specific Java type wins over a converter for a less specific Java type, even when the less specific converter is in an earlier scope.

If no discovered converter matches an unnamed type lookup, Kaumei JDBC may then inspect the used Java type and create or discover a missing converter.

@JdbcConverterName requests name-based lookup. Name lookup is exact and does not inspect the used Java type.

For parameter binding, the name is read from @JdbcConverterName on the method parameter. For result mapping, the name is read from @JdbcConverterName on the method.

The selected converter must also be type-compatible with the use:

  • for parameter binding, the Java parameter type must be a subtype of the converter input type
  • for result mapping, the converter result type must be assignable to the Java result type

If no converter with the requested name exists, or the converter is incompatible, converter selection is invalid.

Unnamed parameter binding uses @JavaToJdbc type lookup. The lookup first checks for an exact type match in the general search order.

If no exact match exists, Kaumei JDBC checks assignable Java supertypes. For each converter type candidate, the local, global, and basic scopes are searched before the next less specific type candidate is considered. A more specific converter input type wins over a less specific converter input type, even when the less specific converter is in an earlier scope.

An unnamed Java-to-JDBC converter matches when the method parameter type is a subtype of the converter input type. If multiple matching converter input types are unrelated in the type hierarchy, converter selection is ambiguous and invalid.

Kaumei JDBC inspects the used Java type only after exact and hierarchy lookup fail. The used type may provide an unnamed @JavaToJdbc converter method. If it does not:

  • an enum can use its name as a String value
  • a record with exactly one component can use that component as its JDBC value

Nested component conversion uses the dependency context of the created converter. Default parameter converters are described in parameter binding.

Unnamed result mapping uses @JdbcToJava type lookup. The lookup checks for an exact type match in the general search order. It does not search the Java type hierarchy.

Only after exact lookup fails does Kaumei JDBC inspect the used Java type. The used type may provide an unnamed @JdbcToJava converter method or constructor. If it does not, an enum can use valueOf(String), and a class or record can use exactly one usable constructor as its default converter. Constructor parameters must be convertible in the converter dependency context. Default result converters are described in result mapping.

Nested converter lookup uses the owning scope of the converter that needs the dependency. A local converter searches its owning JDBC interface’s local scope, then global, then basic. A global converter searches global, then basic. A basic converter searches only the basic scope.

This applies to record component converters, row converter column converters, constructor parameter converters, and converter method parameter converters.