编译抛出`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 数据。
正在尝试实现映射到包含地图的对象的自定义 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 数据。