Я пытаюсь создать универсальный c интерфейс Дао, который содержит общие методы, но я сталкиваюсь с проблемой при создании метода getById(uid: I)
. Для демонстрации я сделал следующий пример:
data class Customer(
@PrimaryKey(autoGenerate = true) var uid: Long? = null
)
со связанным Dao
@Dao
interface CustomerDao : BaseDao<Customer, Long> {
@Query("SELECT * FROM customers WHERE uid=:uid")
override fun getById(uid: Long): Customer;
}
И BaseDao
выглядит так
@Dao
interface BaseDao<T, in I> {
@Insert
fun insert(entity: T) : Long
fun getById(uid : I) : T
}
Компилятор теперь выдает следующее исключение:
An abstract DAO method must be annotated with one and only one of the following annotations: Insert,Delete,Query,Update,RawQuery
Это известная проблема, которая уже была замечена другими, например здесь , но я не нашел решения. Я думаю, что происходит то, что генератор кода пытается создать реализацию как для getById()
в Customer
, так и для getById()
в BaseDao
, но в последнем случае происходит сбой, поскольку у него нет соответствующей аннотации.
Если я добавлю аннотацию Query
к функции в BaseDao
следующим образом:
@Dao
interface BaseDao<T, in I> {
@Insert
fun insert(entity: T) : Long
@Query("SELECT * FROM some_other_table WHERE uid=:uid")
fun getById(uid : I) : T
}
произойдет нечто очень интересное: сгенерированный код теперь выглядит следующим образом:
public final class CustomerDao_Impl implements CustomerDao {
...
@Override
public Customer getById(final Long uid) {
final String _sql = "SELECT * FROM some_other_table WHERE uid=?";
...
}
...
public Customer getById(final long uid) {
final String _sql = "SELECT * FROM customers WHERE uid=?";
...
}
...
}
Первый метод основан на BaseDao
и использует Long
в качестве аргумента, второй - CustomerDao
и использует long
. Если я использую java.lang.Long
вместо kotlin Long
в CustomerDao
, генерируется только функция из CustomerDao
, и все работает, как задумано. Проблема может быть вызвана тем, как kotlin обрабатывает туземцев и непатентованные средства, но я действительно не знаю, как kotlin работает под капотом, поэтому я ищу помощи.