как дела?
Я сделал реализацию 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
}
}