Jdbi: Kotlin 协变重载的二义性方法错误(缺少桥接方法)

创建于 2019-08-09  ·  8评论  ·  资料来源: jdbi/jdbi

编辑:更新了一个更简单的例子。

根据文档泛型和 JDBI 一起工作,我以前看过这项工作(尽管使用的是旧版本的 JDBI),但由于某种原因,我现在收到一个错误:

org.jdbi.v3.sqlobject.UnableToCreateSqlObjectException: interface Bar 有歧义方法 [public abstract java.lang.Object Foo.baz(java.util.UUID), public abstract java.util.UUID Bar.baz(java.util.UUID )],请使用显式覆盖解决

http://jdbi.org/#_annotations_and_inheritance

我已经尝试过@Override以取得良好的效果,但这并没有改变任何东西。

interface Foo<T> {
    <strong i="12">@SqlQuery</strong>
    fun baz(a: UUID): T
}

interface Bar : Foo<UUID> {
    @SqlQuery("SELECT ClientID " +
              "FROM ClientInstance " +
              "WHERE ClientInstanceID = ?")
    override fun baz(a: UUID): UUID
}

JDBI.inTransactionUnchecked { handle ->
    val tester = handle.attach(Bar::class.java)
    val hest = tester.baz(UUID.fromString("7a949c0e-28db-424a-a449-b118e5175a3b"))
    LOGGER.info { "hest $hest" }
}

最有用的评论

嗨,托尔,
我们测试了一个非常相似的构造在 vanilla Java 中工作: https :
也许我们错过了 Kotlin 的一个案例。 我们应该在此处添加与您的使用相对应的测试,并修复发现的任何错误。

所有8条评论

嗨,托尔,
我们测试了一个非常相似的构造在 vanilla Java 中工作: https :
也许我们错过了 Kotlin 的一个案例。 我们应该在此处添加与您的使用相对应的测试,并修复发现的任何错误。

啊,仔细观察:注意返回类型是不同的, ObjectUUID 。 我预计这意味着 Kotlin 编译器正在发出一种我们无法正确处理的合成桥接方法。

对于搜索谷歌的人来说,当父界面没有注释时,这个错误会产生不同的错误消息(我花了一段时间才找到这个!)

Exception in thread "main" java.lang.IllegalStateException: Method StringRepo.get must be default or be annotated with a SQL method annotation.
    at org.jdbi.v3.sqlobject.SqlObjectFactory.lambda$buildMethodHandler$15(SqlObjectFactory.java:148)
...
interface Repo<T> {
    fun get(): T
}
interface StringRepo : Repo<String> {
    @SqlQuery("SELECT 'Hello world!'")
    override fun get(): String
}
//...snip
jdbi.onDemand(StringRepo::class.java).get()

@LittleMikeDev ,这是一个稍微不同的问题。 我改进了错误消息,以免误导缺少注释的类: https :

@TorRanfelt ,我对此进行了深入研究,但如何修复它并不明显。 看起来 Kotlin 编译器没有为协变方法专业化发出桥接方法。 我在 Kotlin 错误跟踪器上提交了一个问题: https :

作为一种解决方法,Jdbi 可以模拟所需的桥接方法。 所需的代码最终可能很小,但编写起来非常棘手。 我希望 Kotlin 至少能尽快评估这个问题。

@stevenschlansker感谢您的调查。
Kotlin 之前一定有过这座桥,因为我已经看到它起作用了。 - 这解释了为什么我无法通过恢复到旧版本的 JDBI 使其再次工作。

看起来这是为了保持 Java 6 兼容性的一种妥协:6 不支持接口中的桥接方法,因此 Kotlin 不会发出它们。 这在今天听起来很愚蠢,但在 10 年前可能是有道理的 ;) 希望他们尽快放弃 6 支持,或者至少有条件地启用与后 6 世界的兼容性。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

mcarabolante picture mcarabolante  ·  4评论

kkrgwbj picture kkrgwbj  ·  4评论

jimmyhmiller picture jimmyhmiller  ·  6评论

buremba picture buremba  ·  5评论

qualidafial picture qualidafial  ·  3评论