Android room DAO interface does not work with inheritance

You can solve it.

The issue is not in room restrictions, but in kotlin implementation itself. You are using generic collection method, which by default is processed to List<? extends T> java implementation, but overridden method has List<Foo> return type. Room generator matches method signature and can't find implemented method with same signature, so you get

An abstract DAO method must be annotated with one and only one of the following annotations

The solution is just annotate method parameter in interface with @JvmSuppressWildcards:

fun getSpecialFoo(): List<@JvmSuppressWildcards T>


This seems like it is limitation of the Room library. You can work around it like the following.

@Dao
interface FooDao {
    @Query("SELECT * FROM foo WHERE bar = :bar")
    fun get(bar: Int): List<Foo>

    @Transaction
    fun getSpecialFoo(): List<Foo> {
        return get(1)
    }
}

fun FooDao.wrapper(): Marker<Foo> {
    return Wrapper(this)
}


private class Wrapper(private val dao: FooDao): Marker<Foo> {
    override fun getSpecialFoo() = dao.getSpecialFoo()
}

When you need it to be Marker<Foo>, you can wrapper() to create a wrapper which implement Marker<Foo> by the dao.