【发布时间】:2021-03-19 04:41:14
【问题描述】:
尝试实现映射到包含地图的对象的自定义 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 数据映射到地图?
【问题讨论】:
-
为什么需要自定义
Jsonb类型?使用 jOOQ 的开箱即用类型无法完成的任何事情,它已经处理了您使用此绑定所做的所有事情? -
JOOQ 中已经存在的映射只映射到一个字符串。我想要实现的是将数据库表示映射到
Map<String, Any>。我的Jsonb是一个对象,它包装了具有该类型的字段以避免泛型问题。 @LukasEder -
但是在你的问题中,你没有映射到
Any。您正在映射到Jsonb。在您看来,其他映射何时发生?也许,与其问在这种情况下出了什么问题,不如问如何实现你最终想要实现的目标?在这种情况下,我认为我的回答会对您更有用:) -
哦,我明白了。您不想将
Any映射到Jsonb。您想将JSONB映射到Any! -
好吧,您的代码示例绝对没有暗示要在
JSONB和Jsonb之间进行映射。而且我认为您不必这样做,请参阅我的回答。