连接关闭后 H2 模式消失

Posted

技术标签:

【中文标题】连接关闭后 H2 模式消失【英文标题】:H2 schema disappears after connection is closed 【发布时间】:2020-04-17 21:57:19 【问题描述】:

在 H2 数据库中为单元测试设置架构后,依赖该架构的单元测试找不到它。

import java.sql.DriverManager
Class.forName("org.h2.Driver")

val setupConn = DriverManager.getConnection("jdbc:h2:mem:test_data_metrics;MODE=PostgreSQL", "sa", "")
val setupStmt = setupConn.createStatement

// setup schema at the beginning of our test
setupStmt.execute("CREATE SCHEMA IF NOT EXISTS my_test_schema AUTHORIZATION sa;")
setupStmt.execute("GRANT ALL ON SCHEMA my_test_schema TO sa;")
setupStmt.execute("CREATE TABLE IF NOT EXISTS my_test_schema.my_test_table (test_id VARCHAR(255), test_column VARCHAR(255));")
setupStmt.executeQuery("select * from my_test_schema.my_test_table")
// res4: java.sql.ResultSet = rs3: org.h2.result.LocalResultImpl@3eb10d62 columns: 2 rows: 0 pos: -1
// this seems to work correctly ^^^

setupStmt.close
setupConn.close

// now run our test using the schema we just set up
val conn = DriverManager.getConnection("jdbc:h2:mem:test_data_metrics;SCHEMA=my_test_schema;MODE=PostgreSQL", "sa", "")
val stmt = conn.createStatement

stmt.executeQuery("select * from my_test_table where test_id = '1'")
// org.h2.jdbc.JdbcSQLSyntaxErrorException: Schema "MY_TEST_SCHEMA" not found; SQL statement:
// SET SCHEMA my_test_schema [90079-200]
// ^^^^ something has gone horribly wrong

【问题讨论】:

【参考方案1】:

您可以简单地将;DB_CLOSE_DELAY=-1 添加到JDBC URL;无需活动连接。 https://h2database.com/html/commands.html#set_db_close_delay

如果您使用最新版本的 H2,您可能还需要添加 ;DATABASE_TO_LOWER=TRUE 以更好地与 PostgreSQL 兼容; PostgreSQL 兼容模式本身并不意味着此设置。

【讨论】:

【参考方案2】:

这很尴尬,但我没有意识到当我关闭与内存数据库的连接时,数据库会干涸并被吹走。回想起来,这似乎很明显。解决方案是在整个测试过程中保持与数据库的第一个连接处于打开状态。

import java.sql.DriverManager

Class.forName("org.h2.Driver")

val setupConn = DriverManager.getConnection("jdbc:h2:mem:test_data_metrics;MODE=PostgreSQL", "sa", "")
val setupStmt = setupConn.createStatement

// setup schema at the beginning of our test
setupStmt.execute("CREATE SCHEMA IF NOT EXISTS my_test_schema AUTHORIZATION sa;")
setupStmt.execute("GRANT ALL ON SCHEMA my_test_schema TO sa;")
setupStmt.execute("CREATE TABLE IF NOT EXISTS my_test_schema.my_test_table (test_id VARCHAR(255), test_column VARCHAR(255));")
setupStmt.executeQuery("select * from my_test_schema.my_test_table")
// res4: java.sql.ResultSet = rs3: org.h2.result.LocalResultImpl@3eb10d62 columns: 2 rows: 0 pos: -1

// DON'T CLOSE THE CONNECTION YET!
//setupStmt.close 
//setupConn.close

val conn = DriverManager.getConnection("jdbc:h2:mem:test_data_metrics;SCHEMA=my_test_schema;MODE=PostgreSQL", "sa", "")
val stmt = conn.createStatement

stmt.executeQuery("select * from my_test_table where test_id = '1'")
// res5: java.sql.ResultSet = rs4: org.h2.result.LocalResultImpl@293e66e4 columns: 2 rows: 0 pos: -1
// ^^^^ huzzah!

【讨论】:

以上是关于连接关闭后 H2 模式消失的主要内容,如果未能解决你的问题,请参考以下文章

即使关闭连接后,数据仍然存在于h2数据库表中

为啥hibernate关闭连接后h2的数据库文件仍然会被锁定一段时间?

H2 数据库文件消失

Bootstrap modal 使滚动条在关闭后消失

在 IOS 6.0 中:底部工具栏中的 UIBarButton 在呈现和关闭模式视图控制器后消失

H2 功能特点