【问题标题】:JOOQ ignoring database columns with default valuesJOOQ忽略具有默认值的数据库列
【发布时间】:2013-08-19 01:02:35
【问题描述】:

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(类似于 RETURNING)。

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

【问题讨论】:

    标签: java sql default-value jooq


    【解决方案1】:

    您在这里发现了一些东西(都与 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
    

    插入 NULL 与通过 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

    插入 NULL 与通过 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
    

    我已经注册了

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

    【讨论】:

      猜你喜欢
      • 2015-04-07
      • 2013-02-02
      • 2019-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多