在我的postgresql数据库的表中,我有两列默认值。
我在jOOQ发电机配置中为其中一个定义了一个转换器。
当我执行函数record.store()时,默认值很好地用于没有转换器的字段,但不适用于另一个变为null的字段。
我从未明确设置这些字段,但我认为执行转换后,record.changed(MY_OBJECT.FIELD)== true。
我不确定这是预期的行为。这是一个错误吗?有解决方法吗?
编辑:这是使用的代码
TimestampBinding.java
public class TimestampBinding implements Binding<Timestamp, Instant> {
private static final Converter<Timestamp, Instant> converter = new TimestampConverter();
private final DefaultBinding<Timestamp, Instant> delegate = new DefaultBinding<> (converter());
@Override
public Converter<Timestamp, Instant> converter() { return converter; }
@Override
public void sql(BindingSQLContext<Instant> ctx) throws SQLException {
delegate.sql(ctx);
}
@Override
public void register(BindingRegisterContext<Instant> ctx) throws SQLException {
delegate.register(ctx);
}
@Override
public void set(BindingSetStatementContext<Instant> ctx) throws SQLException {
delegate.set(ctx);
}
@Override
public void set(BindingSetSQLOutputContext<Instant> ctx) throws SQLException {
delegate.set(ctx);
}
@Override
public void get(BindingGetResultSetContext<Instant> ctx) throws SQLException {
delegate.get(ctx);
}
@Override
public void get(BindingGetStatementContext<Instant> ctx) throws SQLException {
delegate.get(ctx);
}
@Override
public void get(BindingGetSQLInputContext<Instant> ctx) throws SQLException {
delegate.get(ctx);
}
}
TimestampConverter.java
public class TimestampConverter implements Converter<Timestamp, Instant> {
@Override
public Instant from(Timestamp ts) {
return ts == null ? null : ts.toInstant();
}
@Override
public Timestamp to(Instant instant) {
return instant == null ? null : Timestamp.from(instant);
}
@Override
public Class<Timestamp> fromType() { return Timestamp.class; }
@Override
public Class<Instant> toType() { return Instant.class; }
}
SQL
CREATE TABLE user (
id uuid PRIMARY KEY,
active boolean NOT NULL DEFAULT false,
created_at timestamptz DEFAULT now()
);
存储记录
user.setId(UUID.randomUUID());
UserRecord userRecord = DSL.using(conn, SQLDialect.POSTGRES_9_3)
.newRecord(userTable.USER, user);
userRecord.store();
答案 0 :(得分:0)
这种行为是“预期的”,在jOOQ中有很长的历史。简短的解释如下:
active
为NOT NULL
,因此无论null
标志如何,Java值DEFAULT
都被解释为SQL值Record.changed()
。< / LI>
created_at
可以为空,因此会解释Java值null
DEFAULT
Record.changed(CREATED_AT) == false
NULL
Record.changed(CREATED_AT) == true
当您致电DSLContext.newRecord()
时,您正在将user
POJO中的所有值复制到userRecord
,包括所有null
值。 jOOQ无法区分未经初始化的null
值和明确显示的null
值... null
。
在您的特定情况下,最佳解决方案是声明所有列NOT NULL
(无论如何在概念级别上更好):
CREATE TABLE user (
id uuid PRIMARY KEY,
active boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now()
);