我們正在將應用程式從 spring-boot 2.4.3 升級到 2.7.0。Hibernate 核心版本是 5.6.9.Final。2.7.0 是第一個使用 H2 資料庫 2.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 的專案已經存在(由腳本插入)。但在以前的 H2 資料庫版本中,這不是問題。
我認為這個執行緒與我的有關,但我看不到在 使用 Postman 請求時,H2 資料庫中提出的解決方案 AUTO_INCREMENT 不起作用
uj5u.com熱心網友回復:
AUTO_INCREMENT是 MySQL 及其分支的一個特性。
H2 的新版本只有標準標識列 ( GENERATED { BY DEFAULT | ALWAYS } AS IDENTITY)。H2AUTO_INCREMENT在某些兼容模式下仍然接受和其他一些特定于供應商的子句,但無論如何它們都被轉換為標識列。
GENERATED BY DEFAULT AS IDENTITY列還允許手動插入值(GENERATED ALWAYS BY 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 版本中一樣。
uj5u.com熱心網友回復:
如果您有插入初始資料的腳本,則不要自己插入 ID。
例子:
如果你正在使用
插入練習(id,created_by,created_on,...)
然后替換為
插入練習(created_by,created_on,...)
在升級到使用 H2 2.1.212 的 spring boot 2.7 后,我遇到了同樣的情況。并通過從插入中洗掉 ID 來解決我修改了 data.sql 中的初始資料
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/483673.html
