Android room DAO 接口不适用于继承
Android room DAO interface does not work with inheritance
interface Marker<T : BaseFoo> {
fun getSpecialFoo(): List<T>
}
@Dao
interface FooDao: Marker<Foo> {
@Query("SELECT * FROM foo WHERE bar = :bar")
fun get(bar: Int): List<Foo>
@Transaction
override fun getSpecialFoo(): List<Foo> {
return get(1)
}
}
这导致
An abstract DAO method must be annotated with one and only one of the following annotations: Insert,Delete,Query,Update,RawQuery
但是,Marker
未标记为 @Dao
,并且 FooDao
已覆盖 getSpecialFoo
。为什么仍然显示此错误?
我需要 Marker
因为我需要一个具有某些方法的通用 DAO。有办法解决这个问题吗?
我能想到的唯一方法是将 dao 标记为 Any
并转换类型运行时或为 DAO 构建包装器。
这似乎是 Room 库的限制。您可以像下面这样解决它。
@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()
}
当你需要它是 Marker<Foo>
时,你可以 wrapper()
创建一个由 dao
.
实现 Marker<Foo>
的包装器
你能解决。
问题不在于房间限制,而在于 kotlin 实现本身。您正在使用通用集合方法,默认情况下处理为 List<? extends T>
java 实现,但覆盖方法具有 List<Foo>
return 类型。房间生成器匹配方法签名,但找不到具有相同签名的已实现方法,因此您得到
An abstract DAO method must be annotated with one and only one of
the following annotations
解决方案就是在接口中注释方法参数 @JvmSuppressWildcards
:
fun getSpecialFoo(): List<@JvmSuppressWildcards T>
interface Marker<T : BaseFoo> {
fun getSpecialFoo(): List<T>
}
@Dao
interface FooDao: Marker<Foo> {
@Query("SELECT * FROM foo WHERE bar = :bar")
fun get(bar: Int): List<Foo>
@Transaction
override fun getSpecialFoo(): List<Foo> {
return get(1)
}
}
这导致
An abstract DAO method must be annotated with one and only one of the following annotations: Insert,Delete,Query,Update,RawQuery
但是,Marker
未标记为 @Dao
,并且 FooDao
已覆盖 getSpecialFoo
。为什么仍然显示此错误?
我需要 Marker
因为我需要一个具有某些方法的通用 DAO。有办法解决这个问题吗?
我能想到的唯一方法是将 dao 标记为 Any
并转换类型运行时或为 DAO 构建包装器。
这似乎是 Room 库的限制。您可以像下面这样解决它。
@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()
}
当你需要它是 Marker<Foo>
时,你可以 wrapper()
创建一个由 dao
.
Marker<Foo>
的包装器
你能解决。
问题不在于房间限制,而在于 kotlin 实现本身。您正在使用通用集合方法,默认情况下处理为 List<? extends T>
java 实现,但覆盖方法具有 List<Foo>
return 类型。房间生成器匹配方法签名,但找不到具有相同签名的已实现方法,因此您得到
An abstract DAO method must be annotated with one and only one of the following annotations
解决方案就是在接口中注释方法参数 @JvmSuppressWildcards
:
fun getSpecialFoo(): List<@JvmSuppressWildcards T>