J'essaie de définir les méthodes CRUD communes dans une interface de base, comme indiqué ici:
interface BaseDao<in I> {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun create(obj: I)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun createAll(objects: List<I>)
@Delete
fun delete(obj: I)
}
L'interface ProductDao
suivante pour Room hérite de l'interface de base:
@Dao
interface ProductDao : BaseDao<Product> {
// Specific methods
}
Lorsque je compile la définition de fun createAll(objects: List<I>)
, l'erreur suivante est générée:
Le type du paramètre doit être une classe annotée avec @Entity ou une collection/tableau de celle-ci.
Essayez d’ajouter @JvmSuppressWildcards
à votre fonction.
@Insert
@JvmSuppressWildcards
fun createAll(objects: List<I>)
De la docs:
Ordonne au compilateur de générer ou d'omettre les caractères génériques pour les arguments de type correspondant aux paramètres avec variance de site de déclaration, par exemple, comme Collection a.
Cela peut être utile seulement si la déclaration semble être peu pratique à utiliser depuis Java.
J'ai résolu le problème en:
@Dao
interface BaseDao<T> {
/**
* Insert a list in the database. If the item already exists, replace it.
*
* @param list the items to be inserted.
*/
@Insert(onConflict = OnConflictStrategy.REPLACE)
@JvmSuppressWildcards
abstract fun insertAll(kist: List<T>)
}
@JvmSuppressWildcards fait le tour pour moi
Vous devez ajouter l'annotation @Entity
pour votre classe de modèle (vous devez avoir une classe de modèle concrète pour les méthodes Dao), , Mais vous utilisez des génériques dans votre interface BaseDao<in I>
. https://developer.Android.com/training/ data-storage/room/define-data.html
Mon correctif consistait à implémenter l'interface BaseDao
dans Java jusqu'à ce que le problème persiste.
public interface IBaseDao<T> {
@Insert(onConflict = OnConflictStrategy.REPLACE)
@WorkerThread
void save(T item);
@Delete
@WorkerThread
void delete(T item);
@Delete
@WorkerThread
void deleteAll(List<T> items);
@Insert(onConflict = OnConflictStrategy.REPLACE)
@WorkerThread
void saveAll(List<T> items);
}
Résumé BaseDao
in Kotlin
abstract class BaseDao<T> : IBaseDao<T> {
@WorkerThread
open fun getAll(): List<T> = TODO("Override and place the annotation @Query. Ex: @Query(\"SELECT * FROM Model\")")
@WorkerThread
open fun loadAll(): LiveData<List<T>> = TODO("Override and place the annotation @Query. Ex: @Query(\"SELECT * FROM Model\")")
}
Ça marche!
J'ai eu le même problème et je pense avoir trouvé la solution:
Il est impossible pour Kotlin de créer un tableau d'objets génériques. Vous devez donc créer une solution de contournement:
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun create(obj: I)
@Transaction
fun createAll(objects: List<I>) = objects.forEach {insert(it)}
@Transaction
devrait permettre que tout se produise en une seule transaction. Par conséquent, il ne devrait présenter aucun problème de performances, mais je n'en suis pas certain.
De plus, un simple:
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun createAll(objects: List<Product>)
fonctionnera aussi bien, tant qu’il utilisera des objets réels, pas des génériques.