【问题标题】:Binding custom data type transmit null to converter绑定自定义数据类型将 null 传输到转换器
【发布时间】:2018-11-13 21:46:06
【问题描述】:

我在我的项目中使用 Jooq 和 Kotlin。我有对象 EventEnvelope,其中组成了 Event 类型的字段。我想将此字段作为 JSON 存储在我的数据库(postgres)中。我准备了 jooq 自定义数据类型绑定和转换器,如此处所述-> https://www.jooq.org/doc/3.10/manual/code-generation/custom-data-type-bindings/ 下面我粘贴转换器、绑定和 gradle 生成器代码。

我的问题是:

  1. 在 jooq 绑定中使用 kotlin 非 null 类型可以吗?

  2. 这个配置可以吗?我应该改变什么?

  3. 当我想存储值时,我的转换器从 func 获取 null。我不知道为什么会这样。

我不知道该怎么做才能解决它。

class JSONEventConverter constructor(
    private val objectMapper: ObjectMapper,
    private val schemaMatcher: SchemaMatcher
) : Converter<Any, Event> {
    override fun from(databaseObject: Any): Event {
        return schemaMatcher.parse(databaseObject.toString())
    }

    override fun to(userObject: Event): Any {
        return objectMapper.writeValueAsString(userObject)
    }

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

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

    companion object {
        fun create(): JSONEventConverter {
            return JSONEventConverter(jacksonObjectMapper(), 
                SchemaMatcher.create())
        }
    }
}

class PostgresJSONEventBinding : Binding<Any, Event> {
    override fun register(ctx: BindingRegisterContext<Event>?) {
        ctx!!.statement().registerOutParameter(ctx.index(), Types.VARCHAR)
    }

    override fun sql(ctx: BindingSQLContext<Event>?) {
        ctx!!.render().visit(DSL.`val`(ctx.convert(converter())
            .value())).sql("::json")
    }

    override fun converter(): Converter<Any, Event> {
        return JSONEventConverter.create()
    }

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

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

    override fun get(ctx: BindingGetSQLInputContext<Event>?) {
        throw SQLFeatureNotSupportedException()
    }

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

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

generator {
    name = 'org.jooq.util.DefaultGenerator'
    strategy {
        name = 'org.jooq.util.DefaultGeneratorStrategy'
    }
    database {
        name = 'org.jooq.util.postgres.PostgresDatabase'
        schemata {
            schema {
                inputSchema = someSchema
            }
            schema {
                inputSchema = otherSchema
            }
        }
        forcedTypes {
            forcedType {
                userType = 'package.Event'
                binding = 'package.PostgresJSONEventBinding'
                expression = 'someSchema\\.event_store\\.event'
            }
        }
    }
    generate {
        relations = true
        deprecated = false
        records = true
        immutablePojos = true
        fluentSetters = true
    }
    target {
        packageName = appName
    }
}

【问题讨论】:

  • 您的问题将 3 个问题合二为一。在这里,要知道你真正想要的是什么有点困难。 究竟您遇到的问题是什么?试着把你的问题集中在那个问题上。回答起来会容易得多。

标签: kotlin jooq


【解决方案1】:

在 jooq 绑定中使用 kotlin 非 null 类型可以吗?

jOOQ(或任何 Java 库)不会尊重您的 Kotlin 不可为空保证,并且可能会在您不期望的地方产生空值。所以,也许这毕竟不是一个好主意。

在 jOOQ 和您的代码之间的接口处,您必须确保自己不会发生这种情况。

这个配置可以吗?我应该改变什么?

这是一个开放式问题。如果您有任何具体问题,请提出。

当我想存储值时,我的转换器从 func 获取 null。我不知道为什么会这样。

您的问题中没有足够的信息来帮助您解决这个问题

【讨论】:

  • 感谢您的回答(一如既往)。我正在再次考虑我的问题以准确地解决我的问题并解决了它。感谢您鼓舞人心的回答。由于这个问题没用,我应该删除它吗?
  • @Piotrowy:不,不要删除它。自己回答吧! :-) 其他人可能仍然觉得它有用...
【解决方案2】:

好吧,就我而言,这是关于 Java 中的可空类型和 kotlin 中的非空类型之间的 java-kotlin 互操作性。我所要做的就是在 kotlin 中使用可空类型实现转换器(带有? 的类型)。

正确的转换器如下所示:

class JSONEventConverter constructor(
    private val objectMapper: ObjectMapper,
    private val schemaMatcher: SchemaMatcher
) : Converter<Any, Event> {
    override fun from(databaseObject: Any?): Event? {
        return databaseObject?.let { schemaMatcher.parse(it.toString()) }
    }

    override fun to(userObject: Event?): Any? {
        return userObject?.let { objectMapper.writeValueAsString(it) }
    }

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

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

    companion object {
        fun create(): JSONEventConverter {
            return JSONEventConverter(serializingObjectMapper(),         
                SchemaMatcher.create())
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-02
    • 1970-01-01
    • 2012-12-14
    • 2013-03-07
    • 2014-06-07
    • 1970-01-01
    • 2011-12-13
    • 2022-01-22
    相关资源
    最近更新 更多