hibernate 从1.4.200更新到2.1.212后,H2自动递增不起作用

unftdfkk  于 2022-11-30  发布在  其他
关注(0)|答案(2)|浏览(182)

我们正在将一个应用程序从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

ryhaxcpt

ryhaxcpt1#

AUTO_INCREMENT是MySQL及其分支的一个特性。
H2的新版本只有标准标识列(GENERATED { BY DEFAULT | ALWAYS } AS IDENTITY)。在某些兼容模式下,H2仍然接受AUTO_INCREMENT和其他一些特定于供应商的子句,但它们都将转换为标识列。
GENERATED BY DEFAULT AS IDENTITY列还允许手动插入值(GENERATED ALWAYS AS IDENTITY子句不允许)。当您插入这样的值时,默认情况下它不会调整序列生成器的基值,这就是您看到此类异常的原因。此行为对于标准标识列是正确的。通常您不应该为它们提供自己的值。

CREATE TABLE TEST(
    ID BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    A INTEGER,
    B INTEGER);
-- Bad insertion, may create problems in the future
INSERT INTO TEST(ID, A, B) VALUES (1, 10, 11), (2, 12, 13);
-- Correct insertion
INSERT INTO TEST(A, B) VALUES (10, 11), (12, 13);
-- Alternative syntax for correct insertion
INSERT INTO TEST(ID, A, B) VALUES (DEFAULT, 10, 11), (DEFAULT, 12, 13);

在插入具有用户提供的值的行后,可以固定标识列生成器的基值:

-- Bad insertion
INSERT INTO TEST(ID, A, B) VALUES (1, 10, 11), (2, 12, 13);
-- Fix
ALTER TABLE TEST ALTER COLUMN ID RESTART WITH (SELECT MAX(ID) FROM TEST) + 1;

在某些兼容性模式下,H2的行为仍然与MySQL和其他一些数据库系统相似,有关详细信息,请参阅它们的文档。在这些模式下,插入用户提供的值会自动调整标识列的生成器,就像在不受支持的旧版本H2中一样。

ubbxdtey

ubbxdtey2#

如果您有插入初始数据的脚本,则不要自己插入ID。
例如:
如果您正在使用

插入到练习中(标识,创建者,创建日期,...)

则替换为

插入练习(创建者、创建日期...)

在升级到使用H2 2.1.212的Sping Boot 2.7后,我遇到了同样的情况,为了解决这个问题,我修改了data.sql中的初始数据,从insert中删除了ID

相关问题