编译抛出`None 以下函数可以使用提供的参数调用`

Compilation throws `None of the following functions can be called with the arguments supplied`

正在尝试实现映射到包含地图的对象的自定义 JSONB 绑定。生成的代码会引发 None of the following functions can be called with the arguments supplied 由以下行引起的错误:

val SOME_FIELD: TableField<SomeRecord, Jsonb?> = createField(DSL.name("meta"), SQLDataType.JSONB.nullable(false).defaultValue(DSL.field("'{}'::jsonb", SQLDataType.JSONB)), this, "", JsonbBinding())

这是我的配置:

class JsonbBinding : Binding<Any, Jsonb> {

    private val mapper = ObjectMapper()

    override fun converter(): Converter<Any, Jsonb> {
        return object : Converter<Any, Jsonb> {
            override fun from(dbObject: Any?): Jsonb {
                if (dbObject == null) return Jsonb()

                val props = mapper.readValue<MutableMap<String, Any>>(dbObject.toString())

                return Jsonb(props)
            }

            override fun to(userObject: Jsonb?): Any? {
                return mapper.writeValueAsString(userObject)
            }

            override fun fromType(): Class<Any> {
                return Any::class.java
            }

            override fun toType(): Class<Jsonb> {
                return Jsonb::class.java
            }

        }
    }

    override fun sql(ctx: BindingSQLContext<Jsonb>) {
        ctx.render()?.let {
            if (it.paramType() == ParamType.INLINED) {
                it.visit(
                    DSL.inline(ctx.convert(converter()).value())
                ).sql("::jsonb")
            } else {
                it.sql("?::jsonb")
            }
        }
    }

    override fun register(ctx: BindingRegisterContext<Jsonb>) {
        ctx.statement().registerOutParameter(ctx.index(), Types.VARCHAR)
    }

    override fun set(ctx: BindingSetStatementContext<Jsonb>) {
        ctx.statement().setString(
            ctx.index(),
            ctx.convert(converter()).value()?.toString()
        )
    }

    override fun set(ctx: BindingSetSQLOutputContext<Jsonb>) {
        throw SQLFeatureNotSupportedException()
    }

    override fun get(ctx: BindingGetResultSetContext<Jsonb>) {
        ctx.convert(converter()).value(ctx.resultSet().getString(ctx.index()))
    }

    override fun get(ctx: BindingGetStatementContext<Jsonb>) {
        ctx.convert(converter()).value(ctx.statement().getString(ctx.index()))
    }

    override fun get(ctx: BindingGetSQLInputContext<Jsonb>) {
        throw SQLFeatureNotSupportedException()
    }
}
<forcedType>
   <userType>org.example.Jsonb</userType>
   <binding>org.example.JsonbBinding</binding>
   <includeExpression>.*</includeExpression>
   <includeTypes>jsonb</includeTypes>
</forcedType>

此外,引起问题的行似乎是将数据库数据映射到 JOOQ 的默认 JSONB 对象。这是导致问题的原因吗?有什么我可能想做的吗?有没有其他方法可以通过 JOOQ 将数据库 JSONB 数据映射到地图?

我认为您在这里混淆了 Binding<T, U> 上的类型变量:

  • T是数据库/JDBC类型(在本例中是org.jooq.JSONB
  • U 是用户类型(在本例中为 Any

您必须以相反的方式实现绑定:Binding<JSONB?, Any?>。由于 jOOQ 已经负责将 JSONB 类型正确绑定到 JDBC,您可能可以单独使用 Converter<JSONB?, Any?> 实现,并将其附加到生成的代码中:

class JsonbConverter : Converter<JSONB?, Any?> { ... }

此外,您不必使用自己的 Jsonb 类型在此处包装 JSON 数据。