Как избежать NumberFormatException при использовании столбца DATETIME в SQLite? - PullRequest
1 голос
/ 01 июня 2019

Я использую базу данных SQLite с таблицами, которые содержат столбцы DATETIME.jOOQ по умолчанию связывает столбцы DATETIME с java.sql.Timestamp.Запрос к таблицам со столбцами DATETIME вызывает исключение NumberFormatException (обработано) для каждого столбца.

Я использую jOOQ 3.11.9.

Исключение выдается в методе анализа org.jooq.impl.DefaultBinding.DefaultTimestampBinding при первой попыткечтобы преобразовать строковое значение метки времени в число.

private static final long parse(Class < ? extends java.util.Date > type, String date) throws SQLException {

    // Try reading a plain number first
    try {
        return Long.valueOf(date);
    }

    // If that fails, try reading a formatted date
    catch (NumberFormatException e) {

        // [#7325] In SQLite dates could be stored in both ISO standard formats:
        //         With T (default standard), or without T (optional standard, JDBC standard)
        date = StringUtils.replace(date, "T", " ");

        if (type == Timestamp.class)
            return Timestamp.valueOf(date).getTime();

        // Dates may come with " 00:00:00". This is safely trimming time information
        else if (type == Date.class)
            return Date.valueOf(date.split(" ")[0]).getTime();

        else if (type == Time.class)
            return Time.valueOf(date).getTime();

        throw new SQLException("Could not parse date " + date, e);
    }
}

При использовании методов get0 и set0 DefaultTimestampBinding метка времени всегда получается / устанавливается как строка.Есть ли причина, по которой для SQLite это не передается в оператор / результат JDBC как метка времени?Есть ли способ переопределить это поведение или избежать исключения?

Override
final void set0(BindingSetStatementContext < U > ctx, Timestamp value) throws SQLException {
    if (ctx.family() == SQLITE)
        ctx.statement().setString(ctx.index(), value.toString());
    else
        ctx.statement().setTimestamp(ctx.index(), value);
}

@Override
final Timestamp get0(BindingGetResultSetContext < U > ctx) throws SQLException {

    // SQLite's type affinity needs special care...
    if (ctx.family() == SQLDialect.SQLITE) {
        String timestamp = ctx.resultSet().getString(ctx.index());
        return timestamp == null ? null : new Timestamp(parse(Timestamp.class, timestamp));
    } else {
        return ctx.resultSet().getTimestamp(ctx.index());
    }
}

1 Ответ

1 голос
/ 05 июня 2019

Хотя вы можете зарегистрировать пользовательскую привязку в генераторе кода, имейте в виду, что эта проблема будет решена в следующем выпуске jOOQ 3.12, а также в следующем выпуске 3.11. Подробнее см. https://github.com/jOOQ/jOOQ/issues/8736.

...