H2数据库插入数据时ID字段NULL值约束报错求助
问题分析与解决方案
直接原因:手动设置ID破坏了自动生成逻辑
你的Book实体已经通过@GeneratedValue(strategy = GenerationType.IDENTITY)配置了数据库自增生成ID,这意味着Hibernate会在插入数据时跳过ID字段,完全由H2数据库的自增机制生成主键值。但你在DAO的saveBook方法里手动执行了book.setId(0L),这直接干扰了这个流程:
- 手动设置ID为
0L后,Hibernate会认为你要插入这个指定值,而非依赖数据库自动生成 - H2的IDENTITY类型列无法识别
0为有效主键值,最终将其解析为NULL,触发非空约束报错
解决步骤
1. 移除DAO中手动设置ID的代码
删除book.setId(0L);这一行,让Hibernate按照配置的策略自动处理ID生成:
public void saveBook(Book book) { Session s = sessionFactory.getCurrentSession(); s.save(book); }
2. 确认数据库表结构的正确性
确保H2数据库中BOOK表的ID列是自增主键,对应的DDL语句示例:
CREATE TABLE BOOK ( ID BIGINT AUTO_INCREMENT PRIMARY KEY, AUTHOR VARCHAR(255), GENRE VARCHAR(255), ILLUSTRATOR VARCHAR(255), SERIES VARCHAR(255), TITLE VARCHAR(255) );
如果是Hibernate自动建表,检查hibernate.hbm2ddl.auto配置是否为update或create,确保表结构被正确生成。
3. 验证Hibernate配置一致性
确认没有其他配置覆盖了IDENTITY策略:
- 检查
application.properties或persistence.xml中没有禁用自动主键生成的参数 - 实体类的
@Id和@GeneratedValue注解没有冲突配置
补充说明
使用GenerationType.IDENTITY时,Hibernate会在插入完成后自动从数据库获取生成的ID并赋值给实体对象,全程不需要手动干预ID字段。手动设置ID值会强制Hibernate插入指定值,这与IDENTITY策略的设计逻辑完全冲突,是本次报错的核心原因。
内容的提问来源于stack exchange,提问作者Matthew Earlywine
相关产品推荐
相关产品推荐

