Как сделать обработку ошибок в Android Room? - PullRequest
0 голосов
/ 15 января 2020

как дела?

Я сделал реализацию Room на основе страницы jetpack, отлично работал в моих тестах, но при добавлении с помощью syn c произошла следующая ошибка:

Caused by: android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY[787])
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:995)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:51)
        at androidx.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:64)
        at br.com.sat.cronos.database.dao.tarefa.TarefaDAO_Impl.inserir(TarefaDAO_Impl.java:142)
        at br.com.sat.cronos.database.dao.tarefa.TarefaDAO_Impl.inserir(TarefaDAO_Impl.java:17)
        at br.com.sat.cronos.repository.tarefa.TarefaRepository$salvar$1.invoke(TarefaRepository.kt:37)
        at br.com.sat.cronos.repository.tarefa.TarefaRepository$salvar$1.invoke(TarefaRepository.kt:11)
        at br.com.sat.cronos.asynctask.BaseAsyncTask.doInBackground(BaseAsyncTask.kt:12)
        at br.com.sat.cronos.asynctask.BaseAsyncTask.doInBackground(BaseAsyncTask.kt:7)
        at android.os.AsyncTask$2.call(AsyncTask.java:333)

Я закончил тем, что создал класс BaseDao для использования в качестве generi c, чтобы я мог использовать его динамически:

package br.com.sat.cronos.database.dao

import androidx.annotation.WorkerThread
import androidx.room.*


@Dao
interface BaseDAO<T> {

    /**
     * Insere um objeto no banco de dados
     *
     * @param obj
     */
    @Insert
    fun inserir(obj: T)

    /**
     * Insere um array de objetos no banco de dados
     *
     * @param list
     */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    @WorkerThread
    fun inserir(list: List<T>)

    /**
     * Atualizar um objeto no banco de dados
     *
     * @param obj
     */
    @Update
    fun atualizar(obj: T)

    /**
     * Remove um objeto do banco de dados
     *
     * @param obj
     */
    @Delete
    fun remover(obj: T)

}

И я делаю вызов следующим образом при вставке:

 fun salvar(ta: Tarefa, callback: (Unit?) -> Unit) {
        try {
            BaseAsyncTask(executar = {
                if (buscaPorId(ta.id) == null) {
                    dao?.inserir(ta)
                } else {
                    dao?.atualizar(ta)
                }
            }, finaliza = callback)
                .execute()
        } catch (erro: Exception) {
            CrashlyticsUtil.enviaErro(context, TAG, erro)
        }
    }

Так что мне интересно, как я мог справиться с ошибкой. Прямо сейчас приложение падает, пока кто-то его использует. Я не хочу делать это sh и отправлять ошибку в мой пользовательский класс CrashlyticsUtil.

ОБНОВЛЕНИЕ

Класс Tarefa

package br.com.sat.cronos.model.tarefa

import androidx.room.*
import br.com.sat.cronos.holder.api.tarefa.TarefaApiHolder
import br.com.sat.cronos.model.equipamento.CategoriaEquipamento
import java.io.Serializable

@Entity(
    foreignKeys = [
        ForeignKey(
            entity = CategoriaEquipamento::class,
            parentColumns = ["ID"],
            childColumns = ["ID_CAT_EQUIPAMENTO"]
        ),
        ForeignKey(
            entity = AgrupadorTarefa::class,
            parentColumns = ["ID"],
            childColumns = ["ID_AGRUP_TAREFA"]
        ),
        ForeignKey(
            entity = Sistema::class,
            parentColumns = ["ID"],
            childColumns = ["ID_SISTEMA"]
        )
    ]
)
open class Tarefa : Serializable {

    @PrimaryKey
    @ColumnInfo(name = "ID")
    var id: Long = 0

    @ColumnInfo(name = "ID_CAT_EQUIPAMENTO")
    var idCategoriaEquipamento: Long = 0

    @ColumnInfo(name = "ID_AGRUP_TAREFA")
    var idAgrupadorTarefa: Long = 0

    @ColumnInfo(name = "ID_SISTEMA")
    var idSistema: Long = 0

    @ColumnInfo(name = "DESCRICAO")
    var descricao: String = ""

    @ColumnInfo(name = "SELECIONADO")
    var selecionado: Boolean = false

    @ColumnInfo(name = "ATENDIMENTO")
    var atendimento: Boolean = false

    @ColumnInfo(name = "ATIVO")
    var ativo: Boolean = true

    constructor()

    constructor(ta: TarefaApiHolder) {
        this.id = ta.id!!
        this.idSistema = ta.idSistema!!
        this.idCategoriaEquipamento = ta.idCategoriaEquipamento!!
        this.idAgrupadorTarefa = ta.idAgrupadorTarefa!!
        this.descricao = ta.descricao!!
        this.selecionado = ta.selecionado!!
        this.atendimento = ta.atendimento!!
        this.ativo = ta.ativo!!
    }

    @Ignore
    constructor(
        id: Long,
        idSistema: Long,
        idCategoriaEquipamento: Long,
        idAgrupadorTarefa: Long,
        descricao: String,
        selecionado: Boolean,
        atendimento: Boolean,
        ativo: Boolean
    ) {
        this.id = id
        this.idSistema = idSistema
        this.idCategoriaEquipamento = idCategoriaEquipamento
        this.idAgrupadorTarefa = idAgrupadorTarefa
        this.descricao = descricao
        this.selecionado = selecionado
        this.atendimento = atendimento
        this.ativo = ativo
    }

    override fun toString(): String {
        return descricao
    }

}
...