H2测试报DataIntegrityViolationException值过长问题咨询
问题场景
项目基于JpaRepository实现数据库持久化层,新增长文本字段后部分测试用例执行失败,抛出如下异常:
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.DataException: could not execute statement at com.Tests.test(Tests.java:43) Caused by: org.hibernate.exception.DataException: could not execute statement at com.Tests.test(Tests.java:43) Caused by: org.h2.jdbc.JdbcSQLDataException: Value too long for column "PAYMENT_TEMPLATES VARCHAR(255)": "... (338)"; SQL statement:
服务连接生产数据库运行无异常,问题根因是测试用H2数据库对未显式指定长度的VARCHAR字段默认设置255字符长度限制。需求为仅通过测试类/测试配置完成参数调整,无需在实体类字段上添加@Column注解即可解决该问题。
可行解决方案
所有方案均仅需修改测试环境配置,不侵入生产代码、不修改实体类注解:
- 方案1:通过H2连接参数修改默认VARCHAR长度
在测试环境数据源配置的JDBC连接串中添加DEFAULT_VARCHAR_LENGTH参数,设置足够大的默认VARCHAR长度即可,示例配置:
该参数会让H2对所有未显式指定长度的VARCHAR字段使用设置的长度值(示例中为1MB),完全覆盖常规长文本存储需求,配置成本最低。# 测试环境application.properties配置 spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DEFAULT_VARCHAR_LENGTH=1048576 - 方案2:自定义测试环境Hibernate方言重映射String类型
新增仅测试目录下生效的自定义H2方言类,将默认VARCHAR类型重映射为长文本类型:
随后在测试配置中指定使用该自定义方言:// 存放在src/test/java目录下,仅测试环境可见 package com.xxx.test.config; import org.hibernate.dialect.H2Dialect; import org.hibernate.type.descriptor.sql.LongVarcharTypeDescriptor; import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; import java.sql.Types; public class TestH2Dialect extends H2Dialect { @Override public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor descriptor) { if (descriptor.getSqlType() == Types.VARCHAR) { return LongVarcharTypeDescriptor.INSTANCE; } return super.remapSqlTypeDescriptor(descriptor); } }
配置后Hibernate在H2中建表时会将所有String类型字段映射为长文本类型,无长度限制。spring.jpa.properties.hibernate.dialect=com.xxx.test.config.TestH2Dialect - 方案3:配置Hibernate全局默认String字段长度
若使用Hibernate 5.4及以上版本,可直接在测试配置中指定String类型的默认列长度,无需自定义类:
该配置会让Hibernate对所有未通过spring.jpa.properties.hibernate.column_length.default_string=1048576@Column显式设置长度的String字段,使用配置的长度值生成表结构。
注意:以上所有配置请仅放在
src/test/resources下的测试配置文件中,不要放到生产环境配置路径下,避免影响生产库的表结构生成逻辑。
内容的提问来源于stack exchange,提问作者dcolazin
相关产品推荐
相关产品推荐

