数据库创建时间不能自动填入的问题| 8月更文挑战

263 阅读2分钟

错误起因

相同代码(将null值插入createTime列中),在移植到另一个环境时发生了

create_time cannot be null

的error,无法往下运作。在代码中临时将createTime设置为

new Date()

使之能够正常运行,但在其他地方又遇到了这个问题。

冲突点

在本地/测试/线上环境没有问题,在DDL中我们指定了:

DEFAULT CURRENT_TIMESTAMP

那么即使不指定该列,在执行DML的时候也应该有一个backup的默认值,为什么到了移植环境,相同的代码会有不同的结果?

原因

看到了这篇文章:

blog.csdn.net/m0_38016951…

其实博主的解释是错误的,注释掉的部分里

explicit_defaults_for_timestamp=true

这段代码才是问题的发生关键。

执行代码

show VARIABLES like "explicit_defaults_for_timestamp"

发现本地和移植环境的结果不同:

  • 本地为off
  • 移植环境为on

根据 oracle官方在 dev文档中的解释如下:

explicit_defaults_for_timestamp

| Command-Line Format | --explicit-defaults-for-timestamp[={OFF|ON}] | | ------------------- | ----------------------------------------------- | | Deprecated | Yes | | System Variable | explicit_defaults_for_timestamp | | Scope | Global, Session | | Dynamic | Yes | | Type | Boolean | | Default Value | OFF |

This system variable determines whether the server enables certain nonstandard behaviors for default values and NULL-value handling in TIMESTAMP columns. By default, explicit_defaults_for_timestamp is disabled, which enables the nonstandard behaviors.

可以知道:

  • 在这个参数为off的情况下,可以将null值插入到not null 的timeStamp中,并最终赋值为对应列的默认值
  • 这个参数在5.6已经被标注为Deprecated了。
  • 这个参数默认是off

吐槽一下,为什么会去修改这个变量,真的属于没想到。。。

解决

临时在所有的DO2DB的代码中加入相关属性值的赋值是最保险的做法了,但是如果是hardCode强行加入的话,很有可能会有遗漏的风险,因此我们做了如下工作:

  1. 收集有相关case的变量
  2. 使用mybatis插件的方式,将补充这部分内容的代码加入到项目中,做一个整体的backup