❗️문제 상황
- H2 버전 2.4.240
- init.sql 파일:
CREATE TABLE IF NOT EXISTS game_room
(
janggi_game_id LONG AUTO_INCREMENT PRIMARY KEY,
room_name VARCHAR(10) NOT NULL,
last_turn VARCHAR(5) NOT NULL CHECK (last_turn IN ('CHO', 'HAN')),
last_played_at TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS piece_position
(
piece_position INT AUTO_INCREMENT PRIMARY KEY,
janggi_game_id LONG NOT NULL,
piece_row INT NOT NULL,
piece_column INT NOT NULL,
piece_type VARCHAR(10) NOT NULL CHECK (piece_type IN
('CHARIOT', 'CANNON', 'HORSE', 'ELEPHANT', 'GUARD', 'SOLDIER',
'GENERAL')),
dynasty VARCHAR(5) NOT NULL CHECK (dynasty IN ('CHO', 'HAN')),
CONSTRAINT fk_game
FOREIGN KEY (janggi_game_id)
REFERENCES game_room (janggi_game_id),
CONSTRAINT uq_position
UNIQUE (janggi_game_id, piece_row, piece_column)
);
- property 파일:
db.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;INIT=RUNSCRIPT FROM 'classpath:/init.sql';TRACE_LEVEL_FILE=3;TRACE_LEVEL_SYSTEM_OUT=3
db.username=sa
db.password=
✉️ 에러메시지:
java.lang.RuntimeException: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Check constraint invalid: "CONSTRAINT_DB: "; SQL statement:
INSERT INTO piece_position(janggi_game_id, piece_row, piece_column, piece_type, dynasty) VALUES(?, ?, ?, ?, ?),(?, ?, ?, ?, ?),(?, ?, ?, ?, ?) [23514-240]
at janggi.infra.dao.JdbcBoardDAO.saveAll(JdbcBoardDAO.java:35)
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Check constraint invalid: "CONSTRAINT_DB: "; SQL statement:
INSERT INTO piece_position(janggi_game_id, piece_row, piece_column, piece_type, dynasty) VALUES(?, ?, ?, ?, ?),(?, ?, ?, ?, ?),(?, ?, ?, ?, ?) [23514-240]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:520)
rdDAO.saveAll(JdbcBoardDAO.java:33)
... 4 more
Caused by: org.h2.message.DbException: The database has been closed [90098-240]
at org.h2.message.DbException.get(DbException.java:223)
... 15 more
Caused by: org.h2.jdbc.JdbcSQLNonTransientConnectionException: The database has been closed [90098-240]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:690)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
... 29 more
💡 원인 파악 및 해결 과정
관련 이슈를 찾아보니 나와 같은 문제를 겪고 있는 사람들이 많았다.
JdbcSQLIntegrityConstraintViolationException with different sessions · Issue #4291 · h2database/h2database
Hi, i updated the H2 version to the newest release 2.4.240 and got following exception when i executed my logic to fill the database: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Inval...
github.com
개발자 측 PR에서는 멀티 세션에서 CHECK (IN (...)) 제약을 평가할 때 발생하는 문제라고 하는데 아직 공식적으로 해결된 버전이 배포가 안된것 같다.
Fix ConditionInConstantSet usage from other sessions by katzyn · Pull Request #4311 · h2database/h2database
Closes #4302. This is a fix for a particular issue about IN conditions with constants in CHECK expressions. I decided to push it separately because it was reported multiple times and there were att...
github.com

즉, 나의 경우엔 여러 세션(커넥션)에서 CHECK 제약조건이 있는 DDL 스트립트가 실행해서 발생하는 오류이다.
`INIT RUNSCRIPT` 옵션은 커넥션을 얻어올때마다 해당 스크립트를 실행한다. 그 과정에서 CHECK제약조건이 있는 init.sql이 실행되다보니 오류가 발생한 것 같다.
이를 현재 해결하기 위해선 버전을 낮춰야한다.
낮은 버전에서는 정상동작한다는 이야기가 많다.


실제로 2.3.232로 낮춰보니 정상동작한다.
