我们正在将一个应用程序从spring-boot 2.4.3升级到2.7.0。Hibernate核心版本是5.6.9.Final。2.7.0是第一个使用H2 db2 .1.212的版本,我们正在使用它进行测试。我根据他们的指南做了一些修改,以迁移到2.0,但我面临一个问题,我还没有找到解决方案。
在某些集成测试中,我们使用sql脚本在运行该类中的测试之前插入数据。例如,脚本在表中插入3个项,然后测试插入第4个项并更新已存在的最初3个项中的一个。
执行插入的测试失败,并出现以下错误
DataIntegrityViolationException. Error message: could not execute statement; SQL [n/a]; constraint ["PRIMARY KEY ON studio.exercise(id) ( /* key:1 */ 1, 'Test Exercise', FALSE, 'TEST', NULL, 1, 'TEST', TIMESTAMP '2021-01-01 16:00:13', NULL, NULL)";
SQL statement: insert into exercise (id, created_by, created_on, modified_by, modified_on, archived, image, organization_id, title, type) values (default, ?, ?, ?, ?, ?, ?, ?, ?, ?) [23505-212]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
它抱怨不能插入id为1的项,因为已经存在另一个id为1的项(由脚本插入),但在以前的H2数据库版本中这不是问题。
我认为此主题与我的主题相关,但我无法理解建议的解决方案AUTO_INCREMENT in H2 database doesn't work when requesting with Postman
2条答案
按热度按时间ryhaxcpt1#
AUTO_INCREMENT
是MySQL及其分支的一个特性。H2的新版本只有标准标识列(
GENERATED { BY DEFAULT | ALWAYS } AS IDENTITY
)。在某些兼容模式下,H2仍然接受AUTO_INCREMENT
和其他一些特定于供应商的子句,但它们都将转换为标识列。GENERATED BY DEFAULT AS IDENTITY
列还允许手动插入值(GENERATED ALWAYS AS IDENTITY
子句不允许)。当您插入这样的值时,默认情况下它不会调整序列生成器的基值,这就是您看到此类异常的原因。此行为对于标准标识列是正确的。通常您不应该为它们提供自己的值。在插入具有用户提供的值的行后,可以固定标识列生成器的基值:
在某些兼容性模式下,H2的行为仍然与MySQL和其他一些数据库系统相似,有关详细信息,请参阅它们的文档。在这些模式下,插入用户提供的值会自动调整标识列的生成器,就像在不受支持的旧版本H2中一样。
ubbxdtey2#
如果您有插入初始数据的脚本,则不要自己插入ID。
例如:
如果您正在使用
插入到练习中(标识,创建者,创建日期,...)
则替换为
插入练习(创建者、创建日期...)
在升级到使用H2 2.1.212的Sping Boot 2.7后,我遇到了同样的情况,为了解决这个问题,我修改了data.sql中的初始数据,从insert中删除了ID