Jdbi: Kesalahan metode ambigu (metode jembatan tidak ada) untuk kelebihan kovarian Kotlin

Dibuat pada 9 Agu 2019  ·  8Komentar  ·  Sumber: jdbi/jdbi

EDIT: Diperbarui dengan contoh yang lebih sederhana.

Menurut generik dokumentasi dan JDBI bekerja bersama, dan saya telah melihat ini berfungsi sebelumnya (walaupun dengan versi JDBI yang lebih lama), tetapi untuk beberapa alasan sekarang saya mendapatkan kesalahan:

org.jdbi.v3.sqlobject.UnableToCreateSqlObjectException: interface Bar memiliki metode ambigu [public abstract java.lang.Object Foo.baz(java.util.UUID), public abstract java.util.UUID Bar.baz(java.util.UUID )], harap selesaikan dengan penggantian eksplisit

http://jdbi.org/#_annotations_and_inheritance

Saya telah mencoba @Override untuk ukuran yang baik tetapi itu tidak mengubah apa pun.

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

Komentar yang paling membantu

Hai Tor,
Kami menguji bahwa konstruksi yang sangat mirip berfungsi di Vanilla Java: https://github.com/jdbi/jdbi/blob/master/sqlobject/src/test/Java/org/jdbi/v3/sqlobject/TestSqlObject.java#L293 - L307
Mungkin kita melewatkan satu kasus untuk Kotlin. Kami harus menambahkan tes yang sesuai dengan penggunaan Anda di sini dan memperbaiki bug apa pun yang ditemukan.

Semua 8 komentar

Hai Tor,
Kami menguji bahwa konstruksi yang sangat mirip berfungsi di Vanilla Java: https://github.com/jdbi/jdbi/blob/master/sqlobject/src/test/Java/org/jdbi/v3/sqlobject/TestSqlObject.java#L293 - L307
Mungkin kita melewatkan satu kasus untuk Kotlin. Kami harus menambahkan tes yang sesuai dengan penggunaan Anda di sini dan memperbaiki bug apa pun yang ditemukan.

Ah, perhatikan lebih dekat: perhatikan bahwa tipe pengembaliannya berbeda, Object vs UUID . Saya berharap ini berarti kompiler Kotlin memancarkan metode jembatan sintetis yang kemudian tidak kami tangani dengan benar.

Untuk orang yang mencari di Google, bug ini menghasilkan pesan kesalahan yang berbeda ketika antarmuka induk tidak diberi anotasi (butuh beberapa saat untuk menemukannya!)

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 , itu masalah yang sedikit berbeda. Saya telah meningkatkan pesan kesalahan agar tidak menyesatkan tentang kelas yang tidak memiliki anotasi: https://github.com/jdbi/jdbi/pull/1590/files#diff -75b1c04d402bd8924262c7fececfcdb1L166

@TorRanfelt , saya menggali lebih dalam tentang ini dan tidak jelas apa yang harus dilakukan untuk memperbaikinya. Sepertinya kompiler Kotlin tidak memancarkan metode jembatan untuk spesialisasi metode kovarian. Saya mengajukan masalah pada pelacak bug Kotlin: https://youtrack.jetbrains.com/issue/KT-33634

Sebagai solusinya, Jdbi dapat meniru metode jembatan yang diperlukan. Kode yang dibutuhkan mungkin kecil tetapi sangat sulit untuk ditulis. Saya harap Kotlin setidaknya akan segera mengevaluasi masalah ini.

@stevenschlansker Terima kasih telah
Kotlin pasti pernah memiliki jembatan ini sebelumnya karena saya telah melihatnya bekerja. - Ini menjelaskan mengapa saya tidak bisa membuatnya berfungsi lagi dengan kembali ke versi JDBI yang lebih lama.

Sepertinya ini adalah kompromi untuk menjaga kompatibilitas Java 6: 6 tidak mendukung metode jembatan di antarmuka, jadi Kotlin tidak memancarkannya. Kedengarannya sangat konyol saat ini, tetapi mungkin masuk akal 10 tahun yang lalu ;) Semoga mereka segera menjatuhkan 6 dukungan, atau setidaknya secara kondisional mengaktifkan kompatibilitas dengan dunia pasca-6.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat