Как исправить ошибку при сохранении списка пользовательских типов данных в базе данных комнаты - PullRequest
0 голосов
/ 27 апреля 2020

Я пытаюсь сохранить список пользовательских типов данных в базе данных комнаты, на самом деле, я хочу, чтобы один столбец содержал список всех транзакций, показывающих, что у меня нет двух таблиц.

account.kt

@Entity(tableName = "account_table")
data class account(

    @ColumnInfo(name="name")
    val name:String,


    @ColumnInfo(name="transaction")

    val transactions:List<transaction>

){
    @PrimaryKey(autoGenerate = true)@ColumnInfo(name="account_id")
    val accountId:Int=0
}

транзакция.kt

data class transaction(
    val amount:Float,
    val description:String,
    val date:String

)

Теперь, когда я запускаю код, я получаю сообщение об ошибке

error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
    private final java.util.List<com.example.ledger.Database.transaction> transactions = null;

                                                                          ^D:\flutterProjects\Ledger\app\build\tmp\kapt3\stubs\debug\com\example\ledger\Database\account.java:10: error: Cannot find setter for field.

    private final int accountId = 0;

D:\flutterProjects\Ledger\app\build\tmp\kapt3\stubs\debug\com\example\ledger\Database\accountsDao.java:19: warning: The query returns some columns [account_id, name, transaction] which are not used by com.example.ledger.Database.transaction. You can use @ColumnInfo annotation on the fields to specify the mapping. com.example.ledger.Database.transaction has some fields [amount, description, date] which are not returned by the query. If they are not supposed to be read from the result, you can mark them with @Ignore annotation. You can suppress this warning by annotating the method with @SuppressWarnings(RoomWarnings.CURSOR_MISMATCH). Columns returned by the query: account_id, name, transaction. Fields in com.example.ledger.Database.transaction: amount, description, date.

    public abstract java.util.List<com.example.ledger.Database.transaction> getTransaction(int id);

                      ^D:\flutterProjects\Ledger\app\build\tmp\kapt3\stubs\debug\com\example\ledger\Database\accountsDao.java:19: error: The columns returned by the query does not have the fields [amount,description,date] in com.example.ledger.Database.transaction even though they are annotated as non-null or primitive. Columns returned by the query: [account_id,name,transaction]

    public abstract java.util.List<com.example.ledger.Database.transaction> getTransaction(int id);

                                                                            ^[WARN] Incremental annotation processing requested, but support is disabled because the following processors are not incremental: androidx.room.RoomProcessor (DYNAMIC).

РЕДАКТИРОВАТЬ

accountDao.kt

@Dao
interface accountsDao {
    @Insert
    fun Insert(account: account)

    @Delete
    fun delete(account: account)

    @Query("SELECT * FROM account_table where account_id = :id ")
    fun getTransaction(id:Int):List<transaction>

}

accountDatabase

@Database(entities = [account::class], version = 1, exportSchema = false)

abstract class accountsDatabase : RoomDatabase() {

    abstract val accountdao: accountsDao

    companion object {

        @Volatile
        private var INSTANCE: accountsDatabase? = null


        fun getInstance(context: Context): accountsDatabase? {

            synchronized(this) {
                // Copy the current value of INSTANCE to a local variable so Kotlin can smart cast.
                // Smart cast is only available to local variables.
                var instance = INSTANCE
                // If instance is `null` make a new database instance.
                if (instance == null) {
                    instance = Room.databaseBuilder(
                        context.applicationContext,
                        accountsDatabase::class.java,
                        "saccount_history_database"
                    )

                        .fallbackToDestructiveMigration()
                        .build()
                    // Assign INSTANCE to the newly created database.
                    INSTANCE = instance
                }
                // Return instance; smart cast to be non-null.
                return instance
            }
        }
    }


}

Я чувствую, что в файле Dao будет какой-то код преобразователя типов, потому что я получаю доступ к List<transaction>

1 Ответ

1 голос
/ 27 апреля 2020

Например, списки, модели, список моделей и т. Д. c. Если вы хотите сохранить некоторые специальные объекты типа, например, в базе данных, вы можете использовать Преобразователи типов. Преобразует ваш пользовательский тип объекта в тип, известный для типов базы данных. Это наиболее полезная функция постоянной библиотеки комнаты.

account.kt:

@Entity(tableName = "account_table")
data class account(

@PrimaryKey(autoGenerate = true)@ColumnInfo(name="account_id")
val accountId:Int=0,

@ColumnInfo(name="name")
val name:String,

@TypeConverters(Converters::class)
@ColumnInfo(name="transaction")
val transactions:List<transaction>

)

Converters.kt:

class Converters {

    @TypeConverter
    fun fromTransactionList(transaction: List<transaction?>?): String? {
        if (transaction == null) {
            return null
        }
        val gson = Gson()
        val type: Type = object : TypeToken<List<transaction?>?>() {}.type
        return gson.toJson(transaction, type)
    }

    @TypeConverter
    fun toTransactionList(transactionString: String?): List<transaction>? {
        if (transactionString == null) {
            return null
        }
        val gson = Gson()
        val type =
            object : TypeToken<List<transaction?>?>() {}.type
        return gson.fromJson<List<transaction>>(transactionString, type)
    }

}

Вы можете добавить вот так:

@Database(entities = [account::class], version = 1, exportSchema = false)
@TypeConverters(Converters::class)
abstract class accountsDatabase : RoomDatabase() 

И учетные записи интерфейсаDao:

@Query("SELECT * FROM account_table where account_id = :id ")
fun getTransaction(id:Int):List<account>

используя:

GlobalScope.launch {
   val db = accountsDatabase.getInstance(applicationContext)
   val accounts = db.accountDao().getTransaction(your_id)
   val transactions = accounts[position].transactions
   transactions?.forEach {
            Log.d("Transaction Description" ,it.description)
        }
}
...