Search code examples
javajooqjsonschema2pojo

How can I map Jooq with field joda.time.DateTime to a Pojo with java.time.Instant


I have jooq create TableImpl POJO name CONNECTOR with variable joda.time.DateTime

and jsonschema2pojo create POJO name JsonConnector with variable java.time.Instant

how to convert jooq select result fetch to jsonschema2pojo create obj

List <JsonConnector> list = ctx.select(
    CONNECTOR.INT1,
    CONNECTOR.STRING1,
    CONNECTOR.STRING2,
    CONNECTOR.STRING3,
    CONNECTOR.STRING4,
    CONNECTOR.JODA_TIME_DATETIME))
    .from(CONNECTOR)
    .fetchInto(JsonConnector.class);

jooq fetchInto jsonschema2pojo everything simple type convert is ok, but pojo type org.joda.time.DateTime to type java.time.Instant

that will throw exception org.jooq.exception.MappingException: An error ocurred when mapping record to class JsonConnector

how can I write function like TableField<ConnectorRecord, Instant> convertDateTimeToInstant(TableField<ConnectorRecord, DateTime> datatimeField) or something good method

Thanks


Solution

  • Register a global ConverterProvider

    For the particular use-case you have here, you can implement a ConverterProvider that is able to convert between these two data types. ConverterProvider is an SPI that allows to override the default data type conversions between two data types, such as DateTime and Instant, in both directions.

    Roughly:

    class MyConverterProvider implements ConverterProvider {
        final ConverterProvider delegate = new DefaultConverterProvider();
        
        @Override
        public <T, U> Converter<T, U> provide(Class<T> tType, Class<U> uType) {
            if (tType == DateTime.class && uType == Instant.class) {
                return Converter.ofNullable(tType, uType,
                    t -> (U) dateTimeToInstant((DateTime) t),
                    u -> (T) instantToDateTime((Instant) u)
                );
            }
            
            // Delegate all other type pairs to jOOQ's default
            else
                return delegate.provide(tType, uType);
        }
    }
    

    You then set that to your local or global Configuration:

    configuration.set(new MyConverterProvider());
    

    Using a local ad-hoc converter

    You can always attach a local ad-hoc converter to a field, effectively chaining converters

    List <JsonConnector> list = ctx.select(
        CONNECTOR.INT1,
        CONNECTOR.STRING1,
        CONNECTOR.STRING2,
        CONNECTOR.STRING3,
        CONNECTOR.STRING4,
        CONNECTOR.JODA_TIME_DATETIME.convertFrom(d -> dateTimeToInstant(d)))
        .from(CONNECTOR)
        .fetchInto(JsonConnector.class);