【问题标题】:Slick insert into H2, but no data inserted光滑插入H2,但没有插入数据
【发布时间】:2018-10-09 17:03:39
【问题描述】:

我确定我在这里遗漏了一些非常明显的东西 - 我对一个非常简单的 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)来初始化表中的两个基本行。

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

  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的返回ID)是3,正如我所料(我也尝试过插入不执行返回步骤,只是让它返回插入的行数,它返回 1,正如预期的那样),但查看 q 中返回的值,它只是 init 脚本插入的前两行。

我错过了什么?

【问题讨论】:

    标签: scala h2 slick


    【解决方案1】:

    我的假设是您的 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)。

    在这两种情况下,在此调用之后,数据库包含一个有 2 行的 QUESTION 表。

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

    默认情况下,关闭与数据库的最后一个连接会关闭数据库。对于内存数据库,这意味着内容丢失。要保持数据库打开,请将 ;DB_CLOSE_DELAY=-1 添加到数据库 URL。要在虚拟机处于活动状态时保留内存数据库的内容,请使用 jdbc:h2:mem:test;DB_CLOSE_DELAY=-1。

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

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

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

    【讨论】:

    • 谢谢!我正在试验运行脚本符号并删除了关闭延迟标志!
    • 同样的问题解决了添加关闭延迟并从 'classpath:sql/init_script' 中删除 ;INIT=runscript
    猜你喜欢
    • 1970-01-01
    • 2019-03-16
    • 2022-12-20
    • 2018-01-19
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多