You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate插入Device记录时触发ID非空约束错误求助

Spring Boot整合Hibernate插入H2数据库时「NULL not allowed for column 'ID'」错误解决

问题根源

你遇到的错误本质是数据库表的ID列未配置自增属性,虽然实体类用了GenerationType.IDENTITY主键生成策略,但这个策略依赖数据库端的自增字段来自动生成主键值。你的Liquibase Schema里只把ID设为主键且非空,没开启自增,导致Hibernate插入时无法从数据库获取自增ID,最终传了null值触发约束错误。

修复步骤

1. 修改Liquibase Schema,给ID列添加自增配置

在createTable的ID列定义中加入autoIncrement="true"属性,让H2数据库为该列开启自增:

<changeSet id="0003-1" author="mwietecki">
    <createTable tableName="device">
        <column name="id" type="BIGINT" autoIncrement="true">
            <constraints primaryKey="true" nullable="false"/>
        </column>
        <column name="manufacturer" type="VARCHAR(255)"/>
        <column name="model" type="VARCHAR(255)"/>
        <column name="ram" type="INT"/>
        <column name="rom" type="INT"/>
        <column name="color" type="VARCHAR(50)"/>
        <column name="spec" type="VARCHAR(255)"/>
        <column name="quantity" type="INT"/>
    </createTable>
</changeSet>

2. 重新执行数据库迁移

清理旧的表结构并重新执行Liquibase迁移,确保修改后的Schema生效:

  • 嵌入式H2直接删除项目目录下的*.mv.db数据库文件
  • Maven环境执行:mvn liquibase:dropAll && mvn liquibase:update
  • Gradle环境执行:gradle liquibaseDropAll && gradle liquibaseUpdate

3. 确认实体类配置(现有配置已正确)

实体类的主键配置无需修改,@GeneratedValue(strategy = GenerationType.IDENTITY)会让Hibernate自动读取数据库生成的自增ID:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

为什么之前的尝试无效?

你修改DTO、Mapper忽略ID的操作,只能保证不会把DTO中的ID值传递给实体,但问题核心是数据库无法自动生成ID,所以即使实体的ID为null,Hibernate也无法从数据库获取自增值,最终插入时还是会传null到数据库,触发非空约束错误。

内容的提问来源于stack exchange,提问作者m.wietecki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:13:11