編集:より簡単な例で更新されました。
ドキュメントによると、ジェネリックスとJDBIは連携して動作し、この動作は以前に見たことがありますが(JDBIの古いバージョンではありますが)、何らかの理由でエラーが発生します。
org.jdbi.v3.sqlobject.UnableToCreateSqlObjectException:インターフェイスバーにあいまいなメソッドがあります[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" }
}
こんにちはTor、
非常によく似た構造がバニラJavaで機能することをテストしました: https :
おそらく、Kotlinのケースを見逃したのでしょう。 ここであなたの使用に対応するテストを追加し、発見されたバグを修正する必要があります。
ああ、もっと詳しく見てみましょう。リターンタイプが異なるObject
とUUID
です。 これは、Kotlinコンパイラが合成ブリッジメソッドを発行しているため、正しく処理されていないことを意味していると思います。
Googleを検索している人にとって、親インターフェースに注釈が付けられていない場合、このバグは別のエラーメッセージを生成します(これを見つけるのに時間がかかりました!)
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の世界との互換性を有効にします。
最も参考になるコメント
こんにちはTor、
非常によく似た構造がバニラJavaで機能することをテストしました: https :
おそらく、Kotlinのケースを見逃したのでしょう。 ここであなたの使用に対応するテストを追加し、発見されたバグを修正する必要があります。