似乎JOOQ完全忽略了数据库列的默认值。既没有更新ActiveRecord对象也没有在INSERT上跳过此列。相反,它尝试将其设置为NULL,在NOT NULL列上失败。
示例:
CREATE TABLE bug (
foo int,
bar int not null default 42
);
BugRecord b = jooq.newRecord(BUG);
b.setFoo(3);
b.store();
assertNotNull(b.getBar()); // fails
Record r = jooq.select().from(BUG).fetchOne();
assertEquals(new Integer(-1), r.getValue(BUG.BAR)); // fails
// DataMapper pattern
Bug b = new Bug();
b.setFoo(3);
bugDao.insert(b); // Fails because it tries to set "bar" to NULL
我期望的行为是newRecord()使用korrekt值初始化所有默认变量(虽然我知道如果结果是自定义函数的结果,这可能很难:-))。或者INSERT INTO不会使用默认值插入所有未修改的列,然后INSERT INTO后跟一个SELECT,该SELECT从数据库中获取现有的值(类似于RETURNING)。
这真的是一个错误/限制,还是我错过了一些配置选项等等 可以使用“not null default”列吗?
答案 0 :(得分:9)
你在这里发现了一些事情(都与jOOQ 3.1和以前的版本有关):
BugRecord b = jooq.newRecord(BUG);
b.setFoo(3);
b.store();
assertNotNull(b.getBar()); // fails
确实,这将是一个很好的功能。目前,jOOQ仅提取IDENTITY列值。您可以使用INSERT .. RETURNING
语法或UPDATE .. RETURNING
语法明确选择插入或更新后应返回哪些列。但是能够在常规CRUD操作中这样做会好得多。
this thread中也提到了这一点。相关的功能请求是#1859。
您可以通过调用
来解决此问题b.refresh(); // Refresh all columns
b.refresh(BUG.BAR, ...); // Refresh only some columns
UpdatableRecord
插入DEFAULT:Record r = jooq.select().from(BUG).fetchOne();
assertEquals(new Integer(-1), r.getValue(BUG.BAR)); // fails
在我看来,这是一个错误。 jOOQ的CRUD操作应该DEFAULT
值安全。只有那些在store()
/ insert()
/ update()
操作之前显式设置的值才应该在生成的SQL中呈现。我已为此注册了#2698。
DAO
插入DEFAULT:// DataMapper pattern
Bug b = new Bug();
b.setFoo(3);
bugDao.insert(b); // Fails because it tries to set "bar" to NULL
很好听。这对于解决/增强来说是非常重要的,因为POJO每列没有内部“已更改”/“脏”标记。因此,无法知道POJO中null
引用的含义。
另一方面,jOOQ已经知道列是否可以为空。如果jOOQ还维护了有关列上DEFAULT
子句存在的元数据,则可以推断出组合NOT NULL DEFAULT
必须导致:
INSERT INTO bug(foo, bar)
VALUES(3, DEFAULT)
到
UPDATE bug SET bar = DEFAULT WHERE foo = 3
我已注册