Kotlin对JDBI SqlObject的支持提供了UnsupportedOperationException

时间:2018-07-20 07:12:42

标签: kotlin dropwizard jdbi

扩展了列出的in the official Dropwizard documentation的Dropwizard JDBI3设置的Kotlin等效项,如果没有@Bind和JDBI可以使用的Kotlin专用映射魔术,我无法获得自动参数绑定,如{{3} }。代替这个...

data class Thing(val id: Int, val name: String,
                 val nullable: String?,
                 val nullableDefaultedNull: String? = null,
                 val nullableDefaultedNotNull: String? = "not null",
                 val defaulted: String = "default value")

interface ThingDao {
    @SqlUpdate("insert into something (id, name) values (:something.id, :something.name)")
    fun insert(something: Thing)

    @SqlQuery("select id, name from something")
    fun list(): List<Thing>

    ...
}

..我总是要做:

interface ThingDao {
    @SqlUpdate("insert into something (id, name) values (:id, :name)")
    fun insert(@Bind("id") id: Int?, @Bind("name") name: String)

    @SqlQuery("select id, name from something")
    fun list(): List<Thing>

    ...
}

Gradle具有这些JDBI特定的设置:

...
compile "io.dropwizard:dropwizard-jdbi3:1.3.5"
compile "org.jdbi:jdbi3-sqlobject:3.3.0"
compile "org.jdbi:jdbi3-postgres:3.3.0"
compile "org.jdbi:jdbi3-kotlin:3.3.0"
compile "org.jdbi:jdbi3-kotlin-sqlobject:3.3.0"
....

Dropwizard应用程序具有以下运行配置:

override fun run(configuration: MyConfig, environment: Environment) {
    val factory = JdbiFactory()
    val jdbi = factory.build(environment, configuration.database, "postgresql")
    // This is said to install all available plugins and is thus redundant.
    // I have tried to include various combinations of the following in
    // some desperation. None work.
    jdbi.installPlugins()
    jdbi.installPlugin(SqlObjectPlugin())  // This...
    jdbi.installPlugin(KotlinPlugin())
    jdbi.installPlugin(KotlinSqlObjectPlugin())  // ..and this alone are said to do the job
    ...

否则,使用自定义UUID映射,Jackson Kotlin数据对象映射等一切似乎都可以正常运行。

尤其总是使用:something.id的结果是:

java.lang.UnsupportedOperationException: No argument factory registered for 'Thing(...'

1 个答案:

答案 0 :(得分:0)

评论中建议的解决方案全部有效。非常感谢!麻烦似乎出在一个不幸的过程中,即添加正确的库并在导致无法工作的印象的过程中修复代码(我仍然不是批注狂)。

对于可能在其中找到有用之处的任何人的摘要:

  1. 添加@BindBean使得数据类确实可以作为参数。
  2. 忽略@Bind似乎很有效了一段时间,我只是没有注意到...
  3. ..可能也是部分原因,因为我也错误地尝试将其与数据类一起使用:@Bind("something") something: Thing而不是正确的(但仍然不必要)@BindBean("something") something: Thing
  4. 鉴于此,删除@Bind@BindBean是可行的(至少对于第1001个gradle clean构建而言)。
  5. 我删除了compile "org.jdbi:jdbi3-sqlobject:$jdbi_version",但这两种方法似乎对正常工作都没有任何影响(据说Dropwizard已经引用了它)。

记录下来,这些依赖关系似乎现在对我有用:

buildscript {
  ext.kotlin_version = '1.2.51'
  ext.dropwizard_version = '1.3.5'
  ext.jdbi_version = '3.3.0'
  ...
}

...

dependencies {
  compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
  compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"

  compile "io.dropwizard:dropwizard-core:$dropwizard_version"
  compile "io.dropwizard:dropwizard-jdbi3:$dropwizard_version"
  compile "io.dropwizard:dropwizard-auth:$dropwizard_version"
  compile "io.dropwizard:dropwizard-views-freemarker:$dropwizard_version"
  // This is to serve static content from resources/static
  compile "io.dropwizard:dropwizard-assets:$dropwizard_version"

  compile 'com.fasterxml.jackson.module:jackson-module-kotlin:2.9.4'
  compile 'com.fasterxml.jackson.module:jackson-modules-java8:2.9.4'

  // Removed as redundant
  // compile "org.jdbi:jdbi3-sqlobject:$jdbi_version"
  compile "org.jdbi:jdbi3-postgres:$jdbi_version"
  // So, these are still required as Dropwizard doesn't know Kotlin
  compile "org.jdbi:jdbi3-kotlin:$jdbi_version"
  compile "org.jdbi:jdbi3-kotlin-sqlobject:$jdbi_version"

  // Database
  compile 'org.postgresql:postgresql:42.1.4'

  // ...

  testCompile "io.dropwizard:dropwizard-testing:$dropwizard_version"

  // ...
}