升级H2数据库至2.1.210后modified列非空约束报错求助
H2数据库升级后"modified"列非空约束报错解决方法
问题重现
升级H2数据库从1.4.199到2.1.210版本后,测试执行报错:
NULL not allowed for column "modified"
但建表DDL已配置:
modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
数据库连接字符串:
spring.datasource.url=jdbc:h2:mem:abcdb;MODE=MYSQL;DB_CLOSE_DELAY=-1;
原因分析
H2 2.x版本对MySQL兼容模式的处理逻辑与1.4.x存在差异:
- 2.x默认会将表名、列名转换为大写,若实体类映射的是小写列名,会导致默认值规则无法匹配生效
- 对
ON UPDATE CURRENT_TIMESTAMP的语法兼容需要额外参数开启,否则插入时不会自动填充默认值
解决方案
1. 调整H2连接字符串
添加DATABASE_TO_UPPER=false参数避免列名大小写转换导致的映射问题,同时补充MYSQL_INFORMATION_SCHEMA=TRUE增强MySQL兼容:
spring.datasource.url=jdbc:h2:mem:abcdb;MODE=MYSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MYSQL_INFORMATION_SCHEMA=TRUE;
2. 检查代码中的字段赋值
如果插入数据时显式将modified字段设置为null,即使数据库有默认值配置也会触发非空约束报错。需修改代码,插入时不主动赋值该字段,让数据库自动填充默认值:
- 若使用JPA,可根据需求调整
@Column注解的insertable属性 - 若使用MyBatis,确保插入SQL中不包含
modified字段的赋值语句
3. 验证DDL语法兼容性
H2 2.x对MySQL的ON UPDATE语法支持更严格,可先简化DDL保留核心默认值配置:
modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
如果需要更新时自动刷新时间,可通过数据库触发器或ORM框架的更新逻辑来实现。
内容的提问来源于stack exchange,提问作者user124
相关产品推荐
相关产品推荐

