【问题标题】:H2 database content is not persisting on insert and updateH2 数据库内容在插入和更新时不持久
【发布时间】:2020-07-18 01:57:01
【问题描述】:

我正在使用 h2 数据库来测试我的 postgres 流畅功能。

我在下面创建了一个 h2DbComponent:


    trait H2DBComponent extends DbComponent {

      val driver = slick.jdbc.H2Profile
      import driver.api._
      val h2Url = "jdbc:h2:mem:test;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;INIT=runscript from './test/resources/schema.sql'\\;runscript from './test/resources/schemadata.sql'"

      val logger = LoggerFactory.getLogger(this.getClass)

      val db: Database = {
        logger.info("Creating test connection ..................................")
        Database.forURL(url = h2Url, driver = "org.h2.Driver")
      }
    }

在上面的 sn-p 中,我使用 schema.sql 创建表并使用 schemadata.sql 插入单行(记录)。

然后我尝试使用我的测试用例将记录插入到下表中:


    class RequestRepoTest extends FunSuite with RequestRepo with H2DBComponent {

      test("Add new Request") {
        val response = insertRequest(Request("XYZ","tk", "DM", "RUNNING", "0.1", "l1", "file1",
          Timestamp.valueOf("2016-06-22 19:10:25"), Some(Timestamp.valueOf("2016-06-22 19:10:25")), Some("scienceType")))
        val actualResult=Await.result(response,10 seconds)
        assert(actualResult===1)

        val response2 = getAllRequest()
        assert(Await.result(response2, 5 seconds).size === 2)
      }
    }

上面的插入断言可以正常工作,说明记录已插入。但是 getAllRequest() 断言失败,因为输出仍然包含单行(由 schemadata.sql 插入)=> 这意味着 insertRequest 更改没有持久化。然而,下面的语句声明记录被插入,因为插入返回 1 表示插入了一条记录。


    val response = insertRequest(Request("CMP_XYZ","tesco_uk", "DM", "RUNNING", "0.1", "l1", "file1",
        Timestamp.valueOf("2016-06-22 19:10:25"), Some(Timestamp.valueOf("2016-06-22 19:10:25")), 
        Some("scienceType")))
    val actualResult=Await.result(response,10 seconds)

下面是我对 insertRequest 的定义:


    def insertRequest(request: Request):Future[Int]= {
        db.run { requestTableQuery += request }
    }

我无法弄清楚如何查看插入的记录。我需要添加任何属性/配置吗?

【问题讨论】:

  • 您可以查看Acolyte 来对基于 JDBC 的代码进行单元测试(我是其中的贡献者)

标签: postgresql scala playframework h2 slick


【解决方案1】:

但是 getAllRequest() 断言失败,因为输出仍然包含单行(由 schemadata.sql 插入)=> 这意味着 insertRequest 更改没有持久化

我会仔细检查assert(Await.result(response2, 5 seconds).size === 2) 行是否由于大小差异而失败。它会因为其他一些普遍的失败而失败吗?

例如,当INIT 在每个连接上运行时,您可能正在为每个连接重新创建数据库。除非您小心使用 SQL,否则可能会产生诸如“表已存在”之类的错误。将TRACE_LEVEL_SYSTEM_OUT=2; 添加到您的 H2 网址有助于跟踪 H2 正在做什么。

一些建议。

首先,您可以确保您的 SQL 仅在需要时运行。例如,您的 schema.sql 可以添加检查以避免尝试创建表两次:

CREATE TABLE IF NOT EXISTS my_table( my_column VARCHAR NULL );

同样适用于您的schemadata.sql

MERGE INTO my_table KEY(my_column) VALUES ('a') ;

或者,您可以围绕测试建立架构和测试数据(例如,可能在 Scala 代码中,使用 Slick)。您的测试框架可能有办法确保在测试或测试套件之前和之后运行某些东西。

【讨论】:

  • 添加属性“TRACE_LEVEL_SYSTEM_OUT=2;”帮助。在执行每个数据库请求时,它正在创建连接然后断开连接。如果我想在同一个文件“RequestRepoTest”中使用相同的数据库连接进行假设 4 个测试的任何建议。
  • 我不知道如何让 Slick 在不更改操作的情况下以这种方式绝对使用单个连接(如果您真的想尝试这样做,请在创建db)。相反,我建议设置一个场景来围绕一组测试进行测试。这是一个示例:github.com/d6y/example-slick-h2-test
猜你喜欢
  • 1970-01-01
  • 2015-11-07
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多