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

Erro ao sincronizar

Sincronização não está funcionando, aparece a seguinte mensagem:

08-20 23:28:11.028 27991-27991/br.com.alura.agenda E/SQLiteLog: (20) statement aborts at 5: [INSERT INTO Alunos(caminhoFoto,nome,nota,id,endereco,site,telefone) VALUES (?,?,?,?,?,?,?)] datatype mismatch
08-20 23:28:11.038 27991-27991/br.com.alura.agenda E/SQLiteDatabase: Error inserting caminhoFoto=null nome=Rafael nota=7.0 id=76422891-0aa4-4e69-a35b-917edadaf3d8 endereco=rua do rafael site=googlw.com telefone=98989898
    android.database.sqlite.SQLiteDatatypeMismatchException: datatype mismatch (code 20)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:790)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:926)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1581)
        at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1451)
        at br.com.alura.agenda.dao.AlunoDAO.insere(AlunoDAO.java:99)
        at br.com.alura.agenda.dao.AlunoDAO.sincroniza(AlunoDAO.java:174)
        at br.com.alura.agenda.ListaAlunosActivity$3.onResponse(ListaAlunosActivity.java:90)
        at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5297)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
08-20 23:28:11.038 27991-27991/br.com.alura.agenda E/SQLiteLog: (20) statement aborts at 5: [INSERT INTO Alunos(caminhoFoto,nome,nota,id,endereco,site,telefone) VALUES (?,?,?,?,?,?,?)] datatype mismatch
08-20 23:28:11.048 27991-27991/br.com.alura.agenda E/SQLiteDatabase: Error inserting caminhoFoto=null nome=caique nota=4.0 id=cf912f95-44a0-4c11-b7ec-2b382ed3b07c endereco=rua do caique site=googlem.com telefone=188182i3i
    android.database.sqlite.SQLiteDatatypeMismatchException: datatype mismatch (code 20)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:790)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:926)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1581)
        at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1451)
        at br.com.alura.agenda.dao.AlunoDAO.insere(AlunoDAO.java:99)
        at br.com.alura.agenda.dao.AlunoDAO.sincroniza(AlunoDAO.java:174)
        at br.com.alura.agenda.ListaAlunosActivity$3.onResponse(ListaAlunosActivity.java:90)
        at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5297)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
08-20 23:28:17.038 27991-28029/br.com.alura.agenda I/GMPM: Tag Manager is not found and thus will not be used
7 respostas

Fala ai Guilherme, de boa ?

Cara não sei bem o motivo, mas segundo o erro você tá mandando um dado que o banco espera outro, ai o motivo da exception.

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:
                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);

                String inserindoAlunoNaTabelaNova = "INSERT INTO Alunos_novo" +
                        "(id, nome, endereco, telefone, site, nota, caminhoFoto)" +
                        "SELECT id, nome, endereco, telefone, site, nota, caminhoFoto " +
                        "FROM Alunos";
                db.execSQL(inserindoAlunoNaTabelaNova);

                String removendoTabelaAntiga = "DROP TABLE Alunos";
                db.execSQL(removendoTabelaAntiga);

                String alterandoNomeDaTabelaNova = "ALTER TABLE Alunos_novo " +
                        "RENAME TO Alunos";
                db.execSQL(alterandoNomeDaTabelaNova);

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

                List<Aluno> alunos = populaAlunos(c);

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

                for (Aluno aluno:alunos) {

                   db.execSQL(atualizaIdDoAluno, new String[] {geraUUID(), aluno.getId()});
                }

        }

    }

    private String geraUUID() {

        return UUID.randomUUID().toString();

    }

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

        if(aluno.getId() == null){
        aluno.setId(geraUUID());
        }

        ContentValues dados = pegaDadosDoAluno(aluno);
        db.insert("Alunos", null, dados);//erro acusa aqui

    }

    @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);
        c.close();

        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);
        }
        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 resulta

O erro, não sei pq, está acusando na linha que marquei na primeira parte do código, no método Insere.

Chuto que esse onUpgrade tá meio zuado, receio que talvez nunca tenha caído nele, por exemplo.

Então Matheus, eu baixei o projeto do curso, pra ver se o problema realmente era o meu código, no código que baixei do curso, deu o mesmo erro, até a linha foi a mesma! O que devo fazer, já que até o código que baixei do curso está dando o mesmo erro!

solução!

Um chute é que o app já entra na versão mais atual e assim só passa pelo onCreate, faz o seguinte.

Muda a versão do banco para 1, e vai alterando de 1 em 1 até chegar na versão mais atual.

Receio que seja esse o problema

Grande Matheus, obrigado cara, resolvi, fui atualizando de um a um as versões do banco, e resolveu certinho. Man aquele curso de banco de dados com Room, vai ter continuação? Estou curioso pra ver como faz um relacionamento de tabelas no Android.

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