- All Implemented Interfaces:
Function<R,,E> RecordMapper<R,E>
RecordMapper types, which
applies to Record.into(Class), Result.into(Class), and
similar calls.
The mapping algorithm is this:
If <E> is an array type:
The resulting array is of the nature described in Record.intoArray().
Arrays more specific than Object[] can be specified as well,
e.g. String[]. If conversion to the element type of more
specific arrays fails, a MappingException is thrown, wrapping
conversion exceptions.
If the supplied type is an interface or an abstract class
Abstract types are instantiated using Java reflection Proxy
mechanisms. The returned proxy will wrap a HashMap containing
properties mapped by getters and setters of the supplied type. Methods (even
JPA-annotated ones) other than standard POJO getters and setters are not
supported. Details can be seen in Reflect.as(Class).
If <E> is a TableRecord type (e.g. from a
generated record), then its meta data are used:
Generated TableRecord types reference their corresponding generated
Table types, which provide TableField meta data through
Fields.fields(). All target Fields.fields() are looked up in
the source table via Fields.indexOf(Field) and their values are
mapped. Excess source values and missing target values are ignored.
If <E> is a field "value type" and
<R extends Record1<T1>>, i.e. it has exactly one
column:
The configured ConverterProvider is used to look up a
Converter between T1 and E. By default, the
DefaultConverterProvider is used, which can (among other things):
- Map between built-in types
- Map between
Recordtypes and custom types by delegating to theRecord's attachedRecordMapperProvider - Map between
JSONorJSONBand custom types by delegating to Jackson or Gson (if found on the classpath) - Map between
XMLand custom types by delegating to JAXB (if found on the classpath)
Converter is found, that one is used to map to
E.
If a default constructor is available and any JPA
invalid reference
jakarta.persistence.Column
annotations are found on the provided
<E> type, and the jOOQ-jpa-extensions module
is found on the classpath and configured in
Configuration.annotatedPojoMemberProvider(), only those are
used:
invalid reference
jakarta.persistence.Column
- If
<E>contains single-argument instance methods of any visibility annotated withjakarta.persistence.Column, those methods are invoked - If
<E>contains no-argument instance methods of any visibility starting withgetXXXorisXXX, annotated withjakarta.persistence.Column, then matchingsetXXX()instance methods of any visibility are invoked - If
<E>contains instance member fields of any visibility annotated withjakarta.persistence.Column, those members are set
- The same annotation can be re-used for several methods/members
-
must match
invalid reference
jakarta.persistence.Column#name()Field.getName(). All other annotation attributes are ignored - Static methods / member fields are ignored
- Final member fields are ignored
If a default constructor is available and if there are no JPA
jakarta.persistence.Column annotations, or jOOQ can't find the
jakarta.persistence API on the classpath, jOOQ will map
Record values by naming convention:
If Field.getName() is MY_field (case-sensitive!), then
this field's value will be set on all of these (regardless of visibility):
- Single-argument instance method
MY_field(…) - Single-argument instance method
myField(…) - Single-argument instance method
setMY_field(…) - Single-argument instance method
setMyField(…) - Non-final instance member field
MY_field - Non-final instance member field
myField
If Field.getName() is MY_field.MY_nested_field
(case-sensitive!), then this field's value will be considered a nested value
MY_nested_field, which is set on a nested POJO that is passed to
all of these (regardless of visibility):
- Single-argument instance method
MY_field(…) - Single-argument instance method
myField(…) - Single-argument instance method
setMY_field(…) - Single-argument instance method
setMyField(…) - Non-final instance member field
MY_field - Non-final instance member field
myField
If no default constructor is available, but at least one constructor
annotated with ConstructorProperties is available, that one is
used
- The standard JavaBeans
ConstructorPropertiesannotation is used to match constructor arguments against POJO members or getters, if the defaultConstructorPropertiesProvidercan look up the implementation from thejOOQ-mapper-extensions-beansmodule, or if you provide your own. - If the property names provided to the constructor match the record's columns via the aforementioned naming conventions, that information is used.
- If those POJO members or getters have JPA annotations, and the
jOOQ-jpa-extensionsmodule is found on the classpath and configured inConfiguration.annotatedPojoMemberProvider(), those will be used according to the aforementioned rules, in order to mapRecordvalues onto constructor arguments. - If those POJO members or getters don't have JPA annotations, the
aforementioned naming conventions will be used, in order to map
Recordvalues onto constructor arguments. - When several annotated constructors are found, the first one is chosen, randomly.
- When invoking the annotated constructor, values are converted onto constructor argument types
If Kotlin is available and the argument class has Kotlin reflection meta
data available, and Settings.isMapConstructorParameterNamesInKotlin()
is turned on, parameter names are reflected and used.
- The Kotlin compiler adds meta data available for reflection using Kotlin reflection APIs to derive parameter names.
If no default constructor is available, but at least one "matching" constructor is available, that one is used
- A "matching" constructor is one with exactly as many arguments as this record holds fields
- When several "matching" constructors are found, the first one is chosen
(as reported by
Class.getDeclaredConstructors()). This choice is non-deterministic as neither the JVM nor the JDK guarantee any order of methods or constructors. - When
Settings.isMapConstructorParameterNames()is turned on, and parameter names are available through reflection onExecutable.getParameters(), then values are mapped by name, otherwise by index. (see #4627) - When invoking the "matching" constructor, values are converted onto constructor argument types
If no default constructor is available, no "matching" constructor is
available, but Settings.isMapConstructorParameterNames() is turned
on, and parameter names are available through reflection on
Executable.getParameters(), the first constructor is used
- The first constructor is chosen (as reported by
Class.getDeclaredConstructors()). This choice is non-deterministic as neither the JVM nor the JDK guarantee any order of methods or constructors. - When invoking that constructor, values are converted onto constructor argument types
Other restrictions
<E>must provide a default or a "matching" constructor. Non-public default constructors are made accessible usingConstructor.setAccessible(boolean)- primitive types are supported. If a value is
null, this will result in setting the primitive type's default value (zero for numbers, orfalsefor booleans). Hence, there is no way of distinguishingnulland0in that case.
This mapper is returned by the DefaultRecordMapperProvider. You can
override this behaviour by specifying your own custom
RecordMapperProvider in Configuration.recordMapperProvider()
- Author:
- Lukas Eder
- See Also:
-
Constructor Summary
ConstructorsConstructorDescriptionDefaultRecordMapper(RecordType<R> rowType, Class<? extends E> type) Create a newDefaultRecordMapper.DefaultRecordMapper(RecordType<R> rowType, Class<? extends E> type, Configuration configuration) Create a newDefaultRecordMapper. -
Method Summary
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface org.jooq.RecordMapper
apply
-
Constructor Details
-
DefaultRecordMapper
Create a newDefaultRecordMapper.This constructor uses a new
DefaultConfigurationinternally to cache various reflection methods. For better performance, useDefaultRecordMapper(RecordType, Class, Configuration)instead. -
DefaultRecordMapper
public DefaultRecordMapper(RecordType<R> rowType, Class<? extends E> type, Configuration configuration) Create a newDefaultRecordMapper.
-
-
Method Details
-
map
Description copied from interface:RecordMapperMap a record into a POJO.- Specified by:
mapin interfaceRecordMapper<R extends Record,E> - Parameters:
record- The record to be mapped. This is never null.- Returns:
- The mapped value, which may be
nullin some implementations.
-
toString
-