Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Estou com o seguinte erro

03-06 12:11:13.408 15176-15176/br.com.alura.agenda E/SQLiteLog: (20) statement aborts at 5: [INSERT INTO Alunos(caminhoFoto,nome,nota,id,endereco,site,telefone) VALUES (?,?,?,?,?,?,?)] datatype mismatch
03-06 12:11:13.410 15176-15176/br.com.alura.agenda E/SQLiteDatabase: Error inserting caminhoFoto=null nome=Jony nota=6.0 id=1bc8f254-af12-49c0-846b-76a2f8b000c3 endereco=Rua 23 site=jony.com.br telefone=64646467
                                                                     android.database.sqlite.SQLiteDatatypeMismatchException: datatype mismatch (code 20)
                                                                         at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
                                                                         at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782)
                                                                         at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
                                                                         at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
                                                                         at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1474)
                                                                         at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1343)
                                                                         at br.com.alura.agenda.dao.AlunoDAO.insere(AlunoDAO.java:107)
                                                                         at br.com.alura.agenda.dao.AlunoDAO.sincroniza(AlunoDAO.java:198)
                                                                         at br.com.alura.agenda.ListaAlunosActivity$3.onResponse(ListaAlunosActivity.java:92)
                                                                         at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
                                                                         at android.os.Handler.handleCallback(Handler.java:751)
                                                                         at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                         at android.os.Looper.loop(Looper.java:154)
                                                                         at android.app.ActivityThread.main(ActivityThread.java:6077)
                                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
5 respostas

Oi Silvânio, tudo bem?

Segundo a Exception tudo indica que o problema está no tipo de dado que está tentando inserir. Você poderia mandar o código do seu AlunoDAO para eu dar uma olhada?

Abraços.

OK! segue AlunoDAO

package br.com.alura.agenda.dao;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.support.annotation.NonNull;
import android.support.v7.media.MediaRouteDescriptor;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import br.com.alura.agenda.modelo.Aluno;

/**
 * Created by alura on 12/08/15.
 */
public class AlunoDAO extends SQLiteOpenHelper {

    public AlunoDAO(Context context) {
        super(context, "Agenda", null, 4);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "CREATE TABLE Alunos (id INTEGER PRIMARY KEY, " +
                "nome TEXT NOT NULL, " +
                "endereco TEXT, " +
                "telefone TEXT, " +
                "site TEXT, " +
                "nota REAL, " +
                "caminhoFoto TEXT);";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        String sql = "";
        switch (oldVersion) {

            case 1:
                sql = "ALTER TABLE Alunos ADD COLUMN caminhoFoto TEXT";
                db.execSQL(sql); // indo para versao 2

            case 2:

                //Cria nova tabela com ID para UUID
                String criandoTabelaNova = "CREATE TABLE Alunos_novo " +
                        "(id CHAR(36) PRIMARY KEY, " +
                        "nome TEXT NOT NULL, " +
                        "endereco TEXT, " +
                        "telefone TEXT, " +
                        "site TEXT, " +
                        "nota REAL, " +
                        "caminhoFoto TEXT);";
                db.execSQL(criandoTabelaNova);

                //Transfere os dados da tabela Alunos para a nova tabela Alunos_novo
                String inserindoAlunosNaTabelaNova = "INSERT INTO Alunos_novo " +
                        "(id, nome, endereco, telefone, site, nota, caminhoFoto) " +
                        "SELECT id, nome, endereco, telefone, site, nota, caminhoFoto " +
                        "FROM Alunos";
                db.execSQL(inserindoAlunosNaTabelaNova);

                //Destroi a tabela Alunos
                String removendoTabelaAntiga = "DROP TABLE Alunos";
                db.execSQL(removendoTabelaAntiga);

                //Renomeia a Tabela Alunos_novo para Alunos
                String alterandoNomeTabelaNova = "ALTER TABLE Alunos_novo " +
                        "RENAME TO Alunos";
                db.execSQL(alterandoNomeTabelaNova);

            case 3:
                String buscaAlunos = "SELECT * FROM Alunos";
                Cursor cursor = db.rawQuery(buscaAlunos, null);

                List<Aluno> alunos = populaAlunos(cursor);

                String atualizaIdAluno = "UPDATE Alunos SET id=? WHERE id=?";

                for (Aluno aluno : alunos) {
                    //verifica o id e substitui por um UUID
                    db.execSQL(atualizaIdAluno, new String[]{geraUUID(), aluno.getId()});
                }
        }

    }

    //Gera o UUID
    private String geraUUID() {

        return UUID.randomUUID().toString();

    }

    public void insere(Aluno aluno) {

        SQLiteDatabase db = getWritableDatabase();

        insereIdSeNecessario(aluno);

        ContentValues dados = pegaDadosDoAluno(aluno);

        db.insert("Alunos", null, dados);

    }

    //Verifica se já existe ID antes de fornecer um
    private void insereIdSeNecessario(Aluno aluno) {
        if(aluno.getId() == null) {
            aluno.setId(geraUUID()); //Adiciona o ID UUID
        }
    }

    @NonNull
    private ContentValues pegaDadosDoAluno(Aluno aluno) {

        ContentValues dados = new ContentValues();
        dados.put("id",aluno.getId());
        dados.put("nome", aluno.getNome());
        dados.put("endereco", aluno.getEndereco());
        dados.put("telefone", aluno.getTelefone());
        dados.put("site", aluno.getSite());
        dados.put("nota", aluno.getNota());
        dados.put("caminhoFoto", aluno.getCaminhoFoto());
        return dados;
    }

    public List<Aluno> buscaAlunos() {

        String sql = "SELECT * FROM Alunos;";
        SQLiteDatabase db = getReadableDatabase();
        Cursor c = db.rawQuery(sql, null);

        List<Aluno> alunos = populaAlunos(c);

        return alunos;

    }

    @NonNull
    private List<Aluno> populaAlunos(Cursor c) {

        List<Aluno> alunos = new ArrayList<Aluno>();

        while (c.moveToNext()) {
            Aluno aluno = new Aluno();
            aluno.setId(c.getString(c.getColumnIndex("id")));
            aluno.setNome(c.getString(c.getColumnIndex("nome")));
            aluno.setEndereco(c.getString(c.getColumnIndex("endereco")));
            aluno.setTelefone(c.getString(c.getColumnIndex("telefone")));
            aluno.setSite(c.getString(c.getColumnIndex("site")));
            aluno.setNota(c.getDouble(c.getColumnIndex("nota")));
            aluno.setCaminhoFoto(c.getString(c.getColumnIndex("caminhoFoto")));

            alunos.add(aluno);
        }

        c.close();

        return alunos;
    }

    public void deleta(Aluno aluno) {
        SQLiteDatabase db = getWritableDatabase();

        String[] params = {aluno.getId().toString()};
        db.delete("Alunos", "id = ?", params);
    }

    public void altera(Aluno aluno) {
        SQLiteDatabase db = getWritableDatabase();

        ContentValues dados = pegaDadosDoAluno(aluno);

        String[] params = {aluno.getId().toString()};
        db.update("Alunos", dados, "id = ?", params);
    }

    public boolean ehAluno(String telefone) {
        SQLiteDatabase db = getReadableDatabase();
        Cursor c = db.rawQuery("SELECT * FROM Alunos WHERE telefone = ?", new String[]{telefone});
        int resultados = c.getCount();
        c.close();
        return resultados > 0;
    }

    public void sincroniza(List<Aluno> alunos) {

        for (Aluno aluno:alunos) {

            if(existe(aluno)){
                altera(aluno);
            }else{
                insere(aluno);
            }

        }
    }

    private boolean existe(Aluno aluno) {

        SQLiteDatabase db = getReadableDatabase();
        String existe = "SELECT id FROM Alunos WHERE id=? LIMIT 1";
        Cursor cursor = db.rawQuery(existe, new String[]{aluno.getId()});
        int Quant = cursor.getCount();

        return Quant > 0;
    }
}

Oi Silvânio a princípio, está tudo de acordo, exceto o tipo de dado do id contido no onCreate() do AlunoDAO, veja que ele ainda está com INTEGER sendo que agora é um CHAR(36). Caso você tenha desinstalado ou apagado as informações da App era pra dar esse erro mesmo... Pode mudar esse valor para `CHAR(36), desinstalar a App e instalar denovo? Então, você tentar inserir um novo aluno.

Abraços.

solução!

OK, tudo certo.

Depois eu havia feito esta alteração, porem não desinstale o APP. e continuou dando o erro.

Desta forma que você orientou ele eliminou tudo e refez.

Estranho, era pra receber os alunos e inserir normalmente...

Não aparece nenhuma mensagem de erro? Veja se os alunos estão sendo recebidos pelo interceptador do Retrofit.

E uma outra dúvida, você está inserindo normalmente os alunos? Eu digo manualmente mesmo.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software