当前位置: 首页 > 知识库问答 >
问题:

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

凤晨朗
2023-03-14

JOOQ似乎完全忽略了数据库列的默认值。既不会更新ActiveRecord对象,也不会在插入时跳过此列。相反,它尝试将其设置为NULL,这在非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

我所期望的行为是,要么new记录()用korrekt值初始化所有默认变量(尽管我知道如果结果是自定义函数的结果,这可能很困难:-))。或者INSERT INTO不插入所有带有默认值的未修改列,然后INSERT INTO后面跟着一个SELECT,它从数据库中获取现在存在的值(类似于返回)。

这真的是一个缺陷/限制,还是我缺少了一些配置选项等,使得使用“not null default”列成为可能?

共有1个答案

鲁鸿
2023-03-14

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

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

assertNotNull(b.getBar()); // fails

这确实是一个很好的功能。目前,jOOQ只获取标识列值。您可以使用INSERT。。或返回代码。。RETURNING语法,显式选择插入或更新后应返回的列。但在常规的积垢处理中能够做到这一点会好得多。

这篇文章中也提到过。相关功能请求为#1859。

你可以打电话解决这个问题

b.refresh();             // Refresh all columns
b.refresh(BUG.BAR, ...); // Refresh only some columns
Record r = jooq.select().from(BUG).fetchOne();
assertEquals(new Integer(-1), r.getValue(BUG.BAR)); // fails

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

// 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子句的元数据,它可以推断NO NULL DEFAULT的组合必须导致:

INSERT INTO bug(foo, bar)
VALUES(3, DEFAULT)

并向

sql prettyprint-override">UPDATE bug SET bar = DEFAULT WHERE foo = 3

我已经注册了

  • #2699:向生成的代码中添加一些元数据信息
  • #2700:在DAOs的SQL中利用上述元数据
 类似资料:
  • 我正在尝试在vault中配置数据库机密引擎以生成动态凭据。在此期间,尽管我为SQL server提供了自定义有效端口,但vault似乎正在获取命令中提供的默认端口(通过忽略自定义端口)。请参阅截图 有人可以帮助配置vault数据库密钥引擎以使用自定义端口吗。 附加图像的文本版本: C:\WINDOWS\system32 将数据写入数据库/config/my-mssql数据库时出错:发出API请求时

  • 问题内容: 我在模型上有一个字段,其内容是: 然后,我将模型更改为: 当我运行以检查迁移时,发现以下更改: 我不理解为什么Django在表中应用a ,因为我正在 创建 默认值。如果这是正确的,Django如何实现默认值? 有关我的工具的信息: PostgreSQL 9.5; Django 1.11b1; 问题答案: 从ln开始的对django / db / backends / base / sc

  • 问题内容: 我正在寻找将列添加到默认值为0的MySQL数据库的语法 参考 问题答案: 尝试这个: 从链接到的文档中: 要在页面下方查找搜索语法,请执行以下操作: column_definition子句对ADD和CHANGE使用与CREATE TABLE相同的语法。请参见第12.1.17节“创建表语法”。 并从链接页面: 注意那里的DEFAULT这个词。

  • 问题内容: 如何说服Windows使用JDK而不是JRE? 问题是Windows忽略了它,也忽略了我将JDK bin目录作为路径中的第一项的事实。 当我从命令行运行时,它运行1.7 JRE而不是调用我的JDK 1.6安装。 我的猜测是这是1.7特有的问题,Windows 7正在使用注册表进行某些操作。 有想法该怎么解决这个吗? 编辑 :糟糕。我的意思是“路径”时,我在上面写了“ classpath

  • 我为此挣扎了很长时间。我正在更改代码,需要将默认值设置为特立尼达岛的selectOneRadio元素。我有来自数据库的对象(例如称为result)。此对象具有属性decision。在select元素中,value参数的使用方式是。 现在我需要结果。decision为空,将值设置为True。如果值为False,则将值设置为False。如果值为True,则将值设置为True。我在模板中尝试了类似的方法

  • 问题内容: Javascript中是否有Python的defaultdict的等效项?这将是一个Javascript数组,其中可为缺少的键返回的值是可定义的。就像是: 如果没有,您将如何实施? 问题答案: 不,这在JavaScript中是不可能的。顺便说一句,您当然是指 对象 (属性值映射)而不是数组。两种解决方案: 将您的对象实现为,旨在完全实现您想要的功能。但是,它只是一个草稿,目前仅在Fir