H2数据库创建关联表后查询提示accomodation_fare_relations不存在如何解决
问题根因
- 你使用了持久化H2数据库
jdbc:h2:~/test,若之前运行过测试残留了旧库数据,第二次执行时不带IF NOT EXISTS的建表语句会直接抛出异常,而你的代码仅捕获异常打印堆栈,没有终止测试流程,表实际未创建成功就执行了查询语句 - 单元测试场景下没有使用内存级H2数据库,每次测试环境不隔离,极易出现残留数据干扰的问题
- 异常被吞导致你无法感知建表阶段的错误,误判表已经创建成功
修复方案
- 替换H2连接为内存模式,保证每次测试都是全新的干净环境,修改连接代码如下:
// 新增DB_CLOSE_DELAY=-1参数保证连接断开后数据库不销毁,适配单元测试场景 conn = DriverManager.getConnection("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE", "sa", ""); // 手动提交事务前先关闭自动提交 conn.setAutoCommit(false);
- 建表语句增加
IF NOT EXISTS判断,避免重复建表报错:
statement1.execute("CREATE TABLE IF NOT EXISTS accomodation\n" + "(\n" + " id integer NOT NULL,\n" + " type character varying(32) NOT NULL,\n" + " bed_type character varying(32) NOT NULL,\n" + " max_guests integer NOT NULL,\n" + " description character varying(512) NOT NULL,\n" + " CONSTRAINT accomodation_pkey PRIMARY KEY (id)\n" + ");"); // 其余两张表的建表语句同样加上IF NOT EXISTS即可
- 移除setUp方法的try-catch块或者捕获异常后直接抛出运行时异常,不要吞掉建表/插数据阶段的错误,方便问题定位
- 新增@After注解的资源清理方法,测试结束后关闭数据库连接:
@After public void tearDown() throws SQLException { if (conn != null && !conn.isClosed()) { conn.rollback(); conn.close(); } }
内容的提问来源于stack exchange,提问作者Darius Boengiu
相关产品推荐
相关产品推荐

