🚀 4.5 Exclusão de Dados e Integridade

A exclusão de registros no Room pode ser feita de forma simples com a anotação @Delete, ou através de consultas costumizadas com @Query. Um diferencial importante em relação ao SQLite puro é a facilidade de gerenciar a integridade referencial (como apagar todos os gastos ao excluir uma viagem).

Integridade com Chaves Estrangeiras

No Room, configuramos a exclusão em cascata diretamente na entidade Gasto. Isso garante que, se uma viagem for removida, o banco de dados limpe automaticamente todos os gastos vinculados:

@Entity(tableName = "gasto",
        foreignKeys = @ForeignKey(entity = Viagem.class,
                                  parentColumns = "id",
                                  childColumns = "viagem_id",
                                  onDelete = ForeignKey.CASCADE))
public class Gasto {
    @PrimaryKey(autoGenerate = true)
    public Long id;
    
    @ColumnInfo(name = "viagem_id")
    public Long viagemId;
    
    public Double valor;
    public String descricao;
}

Operação de Exclusão no DAO

@Dao
public interface ViagemDao {
    @Delete
    void remover(Viagem viagem);
 
    @Query("DELETE FROM viagem WHERE id = :id")
    void removerPorId(Long id);
}

Implementação na Activity (Java 17)

Ao escolher a opção “Remover” no diálogo de opções, executamos a exclusão em background e atualizamos a listagem:

private void confirmarRemocao() {
    new AlertDialog.Builder(this)
        .setTitle("Remover Viagem")
        .setMessage("Deseja realmente excluir esta viagem e todos os seus gastos?")
        .setPositiveButton("Sim", (dialog, which) -> remover())
        .setNegativeButton("Não", null)
        .show();
}
 
private void remover() {
    var viagemParaRemover = this.viagens.get(viagemSelecionada);
    var id = (Long) viagemParaRemover.get("id");
 
    Executors.newSingleThreadExecutor().execute(() -> {
        var dao = AppDatabase.getDatabase(this).viagemDao();
        dao.removerPorId(id);
 
        runOnUiThread(() -> {
            viagens.remove(viagemSelecionada);
            ((SimpleAdapter) binding.listViewViagens.getAdapter()).notifyDataSetChanged();
            Toast.makeText(this, "Viagem removida!", Toast.LENGTH_SHORT).show();
        });
    });
}

IMPORTANT

Cascata Automática: Graças ao ForeignKey.CASCADE, você não precisa mais se preocupar em deletar manualmente os gastos antes da viagem. O SQLite cuidará da integridade de forma atômica e segura.

TIP

Utilize o método notifyDataSetChanged() no seu adaptador para que a ListView reflita a remoção do item imediatamente, sem a necessidade de recarregar toda a atividade.


⬅️ Capítulo Anterior | Próximo Capítulo ➡️