HSQL插入数据时出现不存在字段的非空约束违反问题排查
插入联合主键表时触发非空约束异常的排查
问题背景
通过以下Liquibase脚本创建了含联合主键的idp_groups表:
<changeSet author="..." id="1661758077399"> <createTable tableName="idp_groups"> <column name="idp_id" type="VARCHAR(255)"> <constraints nullable="false"/> </column> <column name="enterprise_group_id" type="UUID"> <constraints nullable="false"/> </column> </createTable> </changeSet> <changeSet author="..." id="1661758077399-2"> <addPrimaryKey columnNames="idp_id, enterprise_group_id" constraintName="idp_groups_pkey" tableName="idp_groups"/> </changeSet>
插入测试数据的SQL:
insert into idp_groups (idp_id, enterprise_group_id) values ('1234', '10d5584f-f2c6-4534-9224-1758de383cd7'); insert into idp_groups (idp_id, enterprise_group_id) values ('1234', '20d5584f-f2c6-4534-9224-1758de383cd7'); insert into idp_groups (idp_id, enterprise_group_id) values ('2345', '40d5584f-f2c6-4534-9224-1758de383cd7');
测试使用HSQL 2.7.0版本:
<dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>2.7.0</version> <scope>test</scope> </dependency>
测试代码:
@Sql({ "/data/idps.sql", "/data/groups.sql", "/data/idp_groups.sql" }) @Test public void testSyncTask() { when(rbacIdpGroupsClient.getIdpGroups(any(), eq("1234"), any(), any(), any(), any(), any())).thenReturn( getRbacResponseIdp1()); when(rbacIdpGroupsClient.getIdpGroups(any(), eq("2345"), any(), any(), any(), any(), any())).thenReturn( getRbacResponseIdp2()); idpGroupSynchronizer.syncGroupsRbac(); }
执行测试时触发异常:
org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [data/idp_groups.sql]: insert into idp_groups (idp_id, enterprise_group_id) values ('1234', '10d5584f-f2c6-4534-9224-1758de383cd7'); nested exception is java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: NOT NULL check constraint; SYS_CT_10265 table: IDP_GROUPS column: IDP_ENTITY_ID
问题分析
错误提示明确指出IDP_ENTITY_ID列违反非空约束,但你定义的表结构里根本没有这个列,说明实际数据库中的表结构和你通过Liquibase定义的结构不一致,和HSQL本身无关。
可能的原因:
- Liquibase的变更集未完全执行,比如之前有其他变更集给
idp_groups表添加了IDP_ENTITY_ID列并设置为非空,但你没注意到 - 测试环境的数据库存在残留的旧表结构,没有被Liquibase正确初始化覆盖
- 项目中存在其他自动生成表结构的组件(比如JPA/Hibernate的
ddl-auto配置),和Liquibase的定义冲突,自动添加了额外列
解决方案
- 验证实际表结构:在测试中添加查询语句或通过HSQL工具执行
DESCRIBE idp_groups;,确认表中是否存在IDP_ENTITY_ID列 - 核对Liquibase执行日志:检查所有变更集是否都成功执行,没有遗漏或失败的记录
- 排查自动表生成组件:检查项目中是否有JPA/Hibernate等组件开启了自动建表功能,若有需关闭或调整配置,避免和Liquibase冲突
- 清理测试数据库:删除测试库中的旧表,重新执行Liquibase脚本初始化表结构后再运行测试
内容的提问来源于stack exchange,提问作者Rnam
相关产品推荐
相关产品推荐

