我正在使用带有包含DATETIME列的表的SQLite数据库。 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());
}
}
答案 0 :(得分:1)
虽然您可以在代码生成器中注册自定义绑定,但是请注意,此问题将在即将发布的jOOQ 3.12版本以及下一个3.11服务版本中得到解决。有关详细信息,请参见https://github.com/jOOQ/jOOQ/issues/8736。