JOOQ忽略具有默认值的数据库列

lat*_*ell 5 java sql default-value jooq

似乎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
Run Code Online (Sandbox Code Playgroud)

我期望的行为是newRecord()使用korrekt值初始化所有默认变量(虽然我知道如果结果是自定义函数的结果,这可能很难:-)).或INSERT INTO执行不要使用默认值插入所有未修改的列,然后INSERT INTO后跟一个SELECT,该SELECT从数据库中获取现有的值(类似于RETURNING).

这真的是一个错误/限制,还是我错过了一些配置选项等,这使得可以使用"not null default"列?

Luk*_*der 9

你在这里发现了一些东西(都与jOOQ 3.1和以前的版本相关):

从插入返回默认值:

BugRecord b = jooq.newRecord(BUG);
b.setFoo(3);
b.store();          

assertNotNull(b.getBar()); // fails
Run Code Online (Sandbox Code Playgroud)

事实上,这将是一个很好的功能.目前,jOOQ仅提取IDENTITY列值.您可以使用INSERT .. RETURNING语法或UPDATE .. RETURNING语法显式选择在插入或更新后应返回哪些列.但是能够在常规CRUD操作中这样做会好得多.

这个帖子中也提到了这一点.相关的功能请求是#1859.

您可以通过致电解决此问题

b.refresh();             // Refresh all columns
b.refresh(BUG.BAR, ...); // Refresh only some columns
Run Code Online (Sandbox Code Playgroud)

插入NULL与插入DEFAULT通过UpdatableRecord:

Record r = jooq.select().from(BUG).fetchOne();
assertEquals(new Integer(-1), r.getValue(BUG.BAR)); // fails
Run Code Online (Sandbox Code Playgroud)

在我看来,这是一个错误.jOOQ的CRUD操作应该是DEFAULT值得安全的.只有那些在store()/ insert()/ update()操作之前显式设置的值才应该在生成的SQL中呈现.我为此注册了#2698.

插入NULL与插入DEFAULT通过DAO:

// DataMapper pattern
Bug b = new Bug();
b.setFoo(3);
bugDao.insert(b); // Fails because it tries to set "bar" to NULL
Run Code Online (Sandbox Code Playgroud)

很好的抓住.这对于解决/增强来说并不重要,因为POJO每列没有内部"已更改"/"脏"标记.因此,不可能知道nullPOJO 中的参考的含义.

另一方面,jOOQ已经知道列是否可以为空.如果jOOQ还维护了DEFAULT关于列的子句存在的元数据,则可以推断该组合NOT NULL DEFAULT必须导致:

INSERT INTO bug(foo, bar)
VALUES(3, DEFAULT)
Run Code Online (Sandbox Code Playgroud)

UPDATE bug SET bar = DEFAULT WHERE foo = 3
Run Code Online (Sandbox Code Playgroud)

我已经注册了

  • #2699:向生成的代码添加一些元数据信息
  • #2700:从DAO中利用SQL中的上述元数据