光滑插入 H2,但没有插入数据

Slick insert into H2, but no data inserted

我确定我在这里遗漏了一些非常愚蠢的东西 - 我有一个非常简单的 Slick 3.2 设置的单元测试。 DAO 具有如下基本的检索和插入方法:

  override def questions: Future[Seq[Tables.QuestionRow]] =
    db.run(Question.result)

  override def createQuestion(title: String, body: String, authorUuid: UUID): Future[Long] =
    db.run(Question returning Question.map(_.id) += QuestionRow(0l, UUID.randomUUID().toString, title, body, authorUuid.toString))

我有一些单元测试 - 对于我在内存 H2 中使用的测试,并且有一个设置脚本(传递给 jdbcurl)来初始化 table.

中的两个基本行

用于检索的单元测试工作正常,它们获取由初始化脚本插入的两行,我刚刚添加了一个简单的单元测试来创建一行然后检索所有行 - 假设它将获取三行行,但无论我做什么,它只会检索前两个:

  it should "create a new question" in {
    whenReady(questionDao.createQuestion("Question three", "some body", UUID.randomUUID)) { s =>
      whenReady(questionDao.questions(s)) { q =>
        println(s)
        println(q.map(_.title))
        assert(true)
      }
    }
  }

输出显示原始 s(来自 autoinc 的 returning ID)是 3,如我所料(我也试过不执行 [=24= 的插入]ing 步骤并让它 return 插入的行数,如预期的那样 returns 1),但查看 returned in q 的值,其只有初始化脚本插入的前两行。

我错过了什么?

我的假设是您的 JDBC url 类似于 jdbc:h2:mem:test;INIT=RUNSCRIPT FROM 'init.sql' 并且没有使用连接池。

有两种情况:

  1. 连接是通过 keepAliveConnection = true 执行的(或通过将 DB_CLOSE_DELAY=-1 附加到 JDBC url)并且 init.sql 类似于:
DROP TABLE IF EXISTS QUESTION;
CREATE TABLE QUESTION(...);
INSERT INTO QUESTION VALUES(null, ...);
INSERT INTO QUESTION VALUES(null, ...);
  1. 连接是使用 keepAliveConnection = false(默认)执行的(没有将 DB_CLOSE_DELAY=-1 附加到 JDBC url)并且 init.sql 类似于:
CREATE TABLE QUESTION(...);
INSERT INTO QUESTION VALUES(null, ...);
INSERT INTO QUESTION VALUES(null, ...);

questionDao.createQuestion 的调用将打开到您的 H2 数据库的新连接并将触发初始化脚本 (init.sql)。

在这两种情况下,在此调用之后,数据库立即包含一个 QUESTION table 和 2 行。

在场景 (2) 中,此调用后连接关闭并根据 H2 documentation:

By default, closing the last connection to a database closes the database. For an in-memory database, this means the content is lost. To keep the database open, add ;DB_CLOSE_DELAY=-1 to the database URL. To keep the content of an in-memory database as long as the virtual machine is alive, use jdbc:h2:mem:test;DB_CLOSE_DELAY=-1.

questionDao.questions 的调用将打开 一个新的 到您的 H2 数据库的连接,并将再次触发 初始化脚本(init.sql).

在场景 (1) 中,第一个连接(以及数据库内容)保持活动状态,但新连接将重新执行初始化脚本 (init.sql) 并删除数据库内容。

鉴于(在这两种情况下)questionDao.createQuestion returns 3,正如预期的那样,但随后内容丢失,因此对 questionDao.questions 的后续调用将使用新初始化的数据库。