简体   繁体   English

使用 Postgres jsonb 类型时,带有 r2dbc 的 Kotlin Micronaut 数据失败

[英]Kotlin Micronaut Data with r2dbc fails while using Postgres jsonb type

I am trying to set up Micronaut Data r2dbc with Postgres but it fails with我正在尝试使用 Postgres 设置 Micronaut Data r2dbc,但它失败了


    io.r2dbc.postgresql.ExceptionFactory$PostgresqlBadGrammarException: [42804] column blob is of type jsonb but expression is of type character varying

micronautVersion=3.5.1 kotlinVersion=1.6.10 javaVersion=17 micronautVersion=3.5.1 kotlinVersion=1.6.10 javaVersion=17

build.gradle.kts构建.gradle.kts


    val coroutinesVersion = "1.6.0"
    dependencies {
        kapt("io.micronaut.data:micronaut-data-processor")
        // kapt("io.micronaut:micronaut-http-validation")
        // implementation("io.micronaut:micronaut-http-client")
        implementation("io.micronaut:micronaut-jackson-databind")
        implementation("io.micronaut.data:micronaut-data-r2dbc")
        implementation("io.micronaut.kotlin:micronaut-kotlin-runtime")
        implementation("jakarta.annotation:jakarta.annotation-api")
        implementation("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
        implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactive:${coroutinesVersion}")
        implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:${coroutinesVersion}")
        runtimeOnly("ch.qos.logback:logback-classic")
        runtimeOnly("org.postgresql:r2dbc-postgresql")
        implementation("io.micronaut:micronaut-validation")
        implementation("io.micronaut:micronaut-runtime")
        implementation("io.micronaut:micronaut-jackson-databind")
        runtimeOnly("com.fasterxml.jackson.module:jackson-module-kotlin")
    }

Postgres schema Postgres 架构


    CREATE TABLE entity (
        entity_id          TEXT PRIMARY KEY,
        entity_type        TEXT NOT NULL,
        blob               JSONB NOT NULL,
        CREATED_DATE       TIMESTAMP(3) DEFAULT now() NOT NULL
    );

Corresponding Kotlin data class对应的 Kotlin 数据类


    @MappedEntity
    data class Entity(
      @field:Id val entityId: String,
      val entityType: String,
      @TypeDef(type = DataType.JSON) val blob: Any,
      val createdDate: Instant
    )

The test that fails失败的测试


    @Test
    fun testInsert() = runBlocking {
        val now = Instant.now()
        val entity = Entity("entity-uuid-1", "test-entity-type", "{}", now)
        Assertions.assertEquals(entity, entityRepository.save(entity))
    }

The complete project is here完整的项目在这里

It looks like either it's missing a required dependency to convert string to json or need a custom converter for this.看起来要么缺少将字符串转换为 json 所需的依赖项,要么为此需要自定义转换器。 Can someone please help.有人可以帮忙吗。

EDIT: It looks like I was mistaken and the actual problem is with the mapping:编辑:看起来我错了,实际问题出在映射上:

Instead of:代替:

@TypeDef(type = DataType.JSON)

It should be:它应该是:

@field:TypeDef(type = DataType.JSON)

It looks like R2DBC Postgres driver doesn't allow a String to be used for JSONB, which is strange because JDBC is fine.看起来 R2DBC Postgres 驱动程序不允许将String用于 JSONB,这很奇怪,因为 JDBC 很好。 You might want to try creating AttributeConverter to convert it into byte[] .您可能想尝试创建AttributeConverter将其转换为byte[]

I got this working by using我通过使用得到了这个工作

    implementation("io.r2dbc:r2dbc-postgresql:0.8.12.RELEASE")

instead of代替

    implementation("org.postgresql:r2dbc-postgresql")

The data class was updated to use io.r2dbc.postgresql.codec.Json instead of Any数据类已更新为使用io.r2dbc.postgresql.codec.Json而不是Any

    @MappedEntity
    data class Entity(
      @field:Id val entityId: String,
      val entityType: String,
      @TypeDef(type = DataType.JSON) val blob: Json,
      val createdDate: Instant
    )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM