[英]jOOQ converter implicitly set a value when writing a record
在我的 postgresql 数据库表中,我有 2 列具有默认值。
我在 jOOQ 生成器配置中为其中之一定义了一个转换器。
当我执行函数record.store() 时,默认值很好地用于没有转换器的字段,但不适用于另一个变为空的字段。
我从未明确设置这些字段,但我猜在执行转换器后 record.changed(MY_OBJECT.FIELD) == true 。
我不确定这是预期的行为。 这是一个错误吗? 有解决方法吗?
编辑:这是使用的代码
时间戳绑定.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);
}
}
时间戳转换器.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();
这种行为是“预期的”,在 jOOQ 中有着悠久的历史。 简短的解释在这里:
active
是NOT NULL
,因此无论Record.changed()
标志如何,Java 值null
被解释为 SQL 值DEFAULT
。created_at
为空,因此解释了 Java 值null
Record.changed(CREATED_AT) == false
则作为 SQL 值DEFAULT
Record.changed(CREATED_AT) == true
则作为 SQL 值NULL
通过调用DSLContext.newRecord()
,您将所有值从您的user
POJO 复制到您的userRecord
,包括所有null
值。 jOOQ无法区分null
被uninitalised值和null
是明确...值null
。
在您的特定情况下,最好的解决方案是将所有列声明为NOT NULL
(无论如何在概念级别上更好):
CREATE TABLE user (
id uuid PRIMARY KEY,
active boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now()
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.