绑定自定义数据类型将null传输到转换器

时间:2018-06-04 14:11:05

标签: kotlin jooq

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

我的问题是:

  1. 使用带有jooq绑定的kotlin非null类型是否可以?

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

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

  4. 我没有想法我应该怎么做才能解决它。

    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
        }
    }
    

2 个答案:

答案 0 :(得分:2)

  

使用带有jooq绑定的kotlin非null类型是否可以?

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

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

  

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

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

  

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

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

答案 1 :(得分:0)

好吧,在我的案例中,这是关于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())
        }
    }
}