关于 postgresql:Unknown data type \\”JSONB\\” when running tests in play slick with H2 Database | 珊瑚贝

Unknown data type “JSONB” when running tests in play slick with H2 Database


在使用

在 playframework 中运行测试时,我遇到了进化问题未知数据类型:”JSONB”

  • scala 的 playframework v2.6.6
  • 玩滑 v3.0.2
  • play-slick-evolutions v3.0.2
  • PostgreSQL – 42.0.0
  • h2数据库 – 1.4.194

我的 H2DbConnector 如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import entities.StubData._
import org.scalatest.{BeforeAndAfterAll, FunSuite}
import play.api.db.DBApi
import play.api.db.evolutions.Evolutions
import play.api.inject.guice.GuiceApplicationBuilder

trait H2DbConnector extends FunSuite WITH BeforeAndAfterAll {
  val appBuilder = NEW GuiceApplicationBuilder()
    .configure(configuration)

  val injector = appBuilder.injector
  lazy val databaseApi = injector.instanceOf[DBApi]

  override def beforeAll() = {
    Evolutions.applyEvolutions(databaseApi.database(“default”))
  }

  override def afterAll() = {
    Evolutions.cleanupEvolutions(databaseApi.database(“default”))
  }
}

在 application.test.conf

1
2
3
slick.dbs.default.driver =“slick.driver.H2Driver$”
slick.dbs.default.db.driver =“org.h2.Driver”
slick.dbs.default.db.url =“jdbc:h2:mem:play;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=FALSE”

我在 Evolutions 2.sql 文件中遇到了一个问题

1
ALTER TABLE“Messages” ADD COLUMN“metaJson” JSONB NULL;

当我运行 dao 测试时出现类似

的错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
20171221 16:08:40,409 [error] p.a.d.e.DefaultEvolutionsApi UNKNOWN DATA TYPE:“JSONB”; SQL statement:
ALTER TABLE“Messages” ADD COLUMN“metaJson” JSONB NULL [50004194] [ERROR:50004, SQLSTATE:HY004]
[info] OptoutsDaoTest *** ABORTED ***
[info]   play.api.db.evolutions.InconsistentDatabase: DATABASE ‘default’ IS IN an inconsistent state![An evolution has NOT been applied properly. Please CHECK the problem AND resolve it manually BEFORE marking it AS resolved.]
[info]   at play.api.db.evolutions.DatabaseEvolutions.$anonfun$checkEvolutionsState$3(EvolutionsApi.scala:285)
[info]   at play.api.db.evolutions.DatabaseEvolutions.$anonfun$checkEvolutionsState$3$adapted(EvolutionsApi.scala:270)
[info]   at play.api.db.evolutions.DatabaseEvolutions.executeQuery(EvolutionsApi.scala:317)
[info]   at play.api.db.evolutions.DatabaseEvolutions.checkEvolutionsState(EvolutionsApi.scala:270)
[info]   at play.api.db.evolutions.DatabaseEvolutions.evolve(EvolutionsApi.scala:239)
[info]   at play.api.db.evolutions.Evolutions$.applyEvolutions(Evolutions.scala:193)
[info]   at H2DbConnector.beforeAll(H2DbConnector.scala:15)
[info]   at H2DbConnector.beforeAll$(H2DbConnector.scala:14)
[info]   at OptoutsDaoTest.beforeAll(OptoutsDaoTest.scala:5)
[info]   at org.scalatest.BeforeAndAfterAll.liftedTree1$1(BeforeAndAfterAll.scala:212)
[info]  

您能帮我解决这个问题吗?

  • 您可以查看 Acolyte 以”模拟”任何 JDBC 连接,无论运行时的目标数据库是什么
  • 这回答了你的问题了吗?如何解决 H2 中的 JSON 列


我最近在使用 JSONB 和 H2 时也遇到了这个问题。我通过创建 JSONB 到 JSON 的别名来解决它,并让它仅在 H2 上的测试配置文件期间运行。

1
CREATE TYPE“JSONB” AS json;

这不是 JSONB,但 JSONB 与 JSON 的区别(至少在 postgres 中)本质上是读取性能,这对于测试目的并不重要(这么多)。

也许这个例子也有帮助:

这是一个使用flyway的例子。创建一个 sql 条目以在 /resources/db/tests 上为 jsonb 创建一个别名类型,该别名类型仅在测试配置文件上运行。

我们使用的是spring,所以这里是application.yml的入口:

1
2
3
4
5
6
7
8
9
spring:
  profiles: mytest
  datasource:
    continueOnError: FALSE
    url: jdbc:h2:mem:myappdb;DB_CLOSE_ON_EXIT=FALSE;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE
flyway:
   enabled: TRUE
   locations: classpath:db/migration, classpath:db/tests
  [……]

这是 ${project.dir}/resources/db/

的列表

enter

这就是魔法:

在文件的内容中,我创建了一个名为 JSONB 的类型,它基本上是 JSON 类型的别名。注意:据我所知,大写是必要的(特别是当您在创建表时引用它时)因为 H2 似乎自动将类型名称更改为 UPPERCASE:

1
CREATE TYPE“JSONB” AS json;

下面是一个使用这种类型创建表的示例:

1
2
3
4
CREATE TABLE“XXX” (
    id BIGSERIAL PRIMARY KEY,
    my_json_column_name JSONB NOT NULL
);


在hibernate方面,我使用来自 hibernate-types52 的 JsonBinaryType 类型,在此链接上查看更多信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@DATA
@TypeDef(name =“jsonb”, typeClass = com.vladmihalcea.hibernate.type.json.JsonBinaryType.class)
@Entity(name =“XXX”)
@TABLE(name =“XXX”)
public class XXX {

  @TYPE(TYPE =“jsonb”)
  @COLUMN(name =“my_json_column_name”, NULLABLE = FALSE)
  private String myJsonColumnName;

  //OR

  @TYPE(TYPE =“jsonb”)
  @COLUMN(name =“my_json_column_name”, NULLABLE = FALSE)
  private List<MYCustomTypeThatMatchesJsonObject> myJsonColumnName;

}

我希望它可以帮助某人。它对我有用。

于 2020 年 7 月 13 日更新

我停止在我的项目中使用 H2 并开始使用测试容器。非常容易设置,您可以在真实的数据库环境中进行测试。

  • 我想强调考虑使用测试容器的建议。


H2 不支持 JSONB 列类型。

所有支持的列类型 H2 支持的数据类型

尝试在测试中也使用 postgres 或编写两个数据库都能理解的标准 SQL 语句。

  • 是否有另一种解决方法来支持 Postgres 和 H2 数据库中的数据类型 JSON?
  • 为 postgres 创建一个测试帐户,并在您的测试中使用 postgres。


当你连接到某个东西时,你不能使用 PostgreSQL 进行单元测试,单元测试应该只在内存测试中进行,因为它会被你的构建触发,而且构建服务器不太可能访问任何物理数据库,你可能需要另一种方法来模拟您的数据并避免从中访问数据库,或者将您的数据类型更改为 string[] 并将其封装以生成 JSON


对于那些在 H2 和 PostgreSQL 数据库中仍然存在这个问题的人,即使在定义了 TypeDef …etc 之后,请在此处查看我的答案


来源:https://www.codenong.com/47924445/

微信公众号
手机浏览(小程序)

Warning: get_headers(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(): Failed to enable crypto in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(https://static.shanhubei.com/qrcode/qrcode_viewid_9817.jpg): failed to open stream: operation failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57
0
分享到:
没有账号? 忘记密码?