简体   繁体   中英

java.lang.RuntimeException in database

I'm making a database for my notes but get an error in my log cat when I run the app. And I don't really get the null part in null, null, null, null. I also don't really understand what is RuntimeException error

Here's my activity:

package com.example.enxin.crystallise;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import java.util.ArrayList;
import java.util.Calendar;


public class NotebookDbAdapter {

private static final String DATABASE_NAME = "notebook.db";
private static final int DATABASE_VERSION = 1;

public static final String NOTE_TABLE = "note";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_TITLE = "title";
public static final String COLUMN_MESSAGE = "message";
public static final String COLUMN_THOUGHTS = "thoughts";
public static final String COLUMN_CATEGORY = "category";
public static final String COLUMN_DATE = "date";

private String[] allColumns = { COLUMN_ID, COLUMN_TITLE, COLUMN_MESSAGE, COLUMN_THOUGHTS,
        COLUMN_CATEGORY, COLUMN_DATE};

public static final String CREATE_TABLE_NOTE = "create table " + NOTE_TABLE + " ( "
        + COLUMN_ID + " integer primary key autoincrement, "
        + COLUMN_TITLE + " text not null, "
        + COLUMN_MESSAGE + " text not null, "
        + COLUMN_THOUGHTS + " text not null, "
        + COLUMN_CATEGORY + " text not null, "
        + COLUMN_DATE + ");";

private SQLiteDatabase sqlDB;
private Context context;

private NotebookDbHelper notebookDbHelper;

public NotebookDbAdapter(Context ctx){
    context = ctx;
}

public NotebookDbAdapter open() throws android.database.SQLException{
    notebookDbHelper = new NotebookDbHelper(context);
    sqlDB = notebookDbHelper.getWritableDatabase();
    return this;
}

public void close(){
    notebookDbHelper.close();
}

public Note createNote(String title, String message, String thoughts, Note.Category category){
    ContentValues values = new ContentValues();
    values.put(COLUMN_TITLE, title);
    values.put(COLUMN_MESSAGE, message);
    values.put(COLUMN_THOUGHTS, thoughts);
    values.put(COLUMN_CATEGORY, category.name());
    values.put(COLUMN_DATE, Calendar.getInstance().getTimeInMillis() + "");

    long insertId = sqlDB.insert(NOTE_TABLE, null, values);

    Cursor cursor = sqlDB.query(NOTE_TABLE,
            allColumns, COLUMN_ID + " = " + insertId, null, null, null, null, null );

    cursor.moveToFirst();
    Note newnote = cursorToNote(cursor);
    cursor.close();
    return newnote;
}

public long deleteNote(long idToDelete){
    return sqlDB.delete(NOTE_TABLE, COLUMN_ID + " = " + idToDelete, null);
}

public long updateNote(long idToUpdate, String newTitle, String newMessage, String newThoughts,
                       Note.Category newCategory){
    ContentValues values = new ContentValues();
    values.put(COLUMN_TITLE, newTitle);
    values.put(COLUMN_MESSAGE, newMessage);
    values.put(COLUMN_THOUGHTS, newThoughts);
    values.put(COLUMN_CATEGORY, newCategory.name());
    values.put(COLUMN_DATE, Calendar.getInstance().getTimeInMillis() + "");

    return sqlDB.update(NOTE_TABLE, values, COLUMN_ID + " = " + idToUpdate, null);
}

public ArrayList<Note> getAllNotes(){
    ArrayList<Note> notes = new ArrayList<Note>();

    //grab all of the information in our database for the notes in it
    Cursor cursor = sqlDB.query(NOTE_TABLE, allColumns, null, null, null, null, null);


    for (cursor.moveToLast(); !cursor.isBeforeFirst(); cursor.moveToPrevious()){
        Note note = cursorToNote(cursor);
        notes.add(note);
    }

    cursor.close();

    return notes;
}

private Note cursorToNote(Cursor cursor){
    Note newNote = new Note (cursor.getString(1), cursor.getString(2),
            Note.Category.valueOf(cursor.getString(3)), cursor.getLong(0), cursor.getLong(4));
    return newNote;
}

private static class NotebookDbHelper extends SQLiteOpenHelper{

    NotebookDbHelper(Context ctx){
        super(ctx, DATABASE_NAME, null , DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db){
        //create note table
        db.execSQL(CREATE_TABLE_NOTE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
        Log.w(NotebookDbHelper.class.getName(),
                "Upgrading database from version " + oldVersion + " to "
        + newVersion + ", which will destroy all old data");
        //destroys data
        db.execSQL("DROP TABLE IF EXISTS " + NOTE_TABLE);
        onCreate(db);
    }
}
}

And here's my logcat:

                                                                         java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.enxin.crystallise/com.example.enxin.crystallise.MainActivity}: android.database.sqlite.SQLiteException: no such column: thoughts (code 1): , while compiling: SELECT _id, title, message, thoughts, category, date FROM note
                                                                             at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
                                                                             at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
                                                                             at android.app.ActivityThread.access$800(ActivityThread.java:135)
                                                                             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
                                                                             at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                             at android.os.Looper.loop(Looper.java:136)
                                                                             at android.app.ActivityThread.main(ActivityThread.java:5001)
                                                                             at java.lang.reflect.Method.invokeNative(Native Method)
                                                                             at java.lang.reflect.Method.invoke(Method.java:515)
                                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
                                                                             at dalvik.system.NativeStart.main(Native Method)
                                                                          Caused by: android.database.sqlite.SQLiteException: no such column: thoughts (code 1): , while compiling: SELECT _id, title, message, thoughts, category, date FROM note
                                                                             at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
                                                                             at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
                                                                             at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
                                                                             at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
                                                                             at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
                                                                             at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
                                                                             at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
                                                                             at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
                                                                             at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1161)
                                                                             at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
                                                                             at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)
                                                                             at com.example.enxin.crystallise.NotebookDbAdapter.getAllNotes(NotebookDbAdapter.java:98)
                                                                             at com.example.enxin.crystallise.MainActivityListFragment.onActivityCreated(MainActivityListFragment.java:39)
                                                                             at android.app.Fragment.performActivityCreated(Fragment.java:1708)
                                                                             at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:908)
                                                                             at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
                                                                             at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1044)
                                                                             at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1853)
                                                                             at android.app.Activity.performCreate(Activity.java:5234)
                                                                             at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
                                                                             at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
                                                                             at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233) 
                                                                             at android.app.ActivityThread.access$800(ActivityThread.java:135) 
                                                                             at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 
                                                                             at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                             at android.os.Looper.loop(Looper.java:136) 
                                                                             at android.app.ActivityThread.main(ActivityThread.java:5001) 
                                                                             at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                             at java.lang.reflect.Method.invoke(Method.java:515) 
                                                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
                                                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
                                                                             at dalvik.system.NativeStart.main(Native Method) 
 **by: android.database.sqlite.SQLiteException: no such column: thoughts** 

seems like there is no column in your database called thoughts , you should fix it.

Runtime exceptions are caught while your application is being executed. In your case the database calls to insert cannot obviously know if such column exists in your Database.

Did you already run a version of this app without the thoughts column implemented? If so you are probably trying to run the cached version of your app, deleting the app and reinstalling should properly install the database with all the columns. You might also try to clear cache on your application, and then run it again.

So I DO see that you are propertly creating this table with the correct column..

public static final String CREATE_TABLE_NOTE = "create table " + NOTE_TABLE
...
+ COLUMN_THOUGHTS + " text not null, "
...

However, my assumption would be that you are continually modifying the database structure.

The problem here, is that on any run of the application, the table will be created, and will be presisted through to the next run - meaning that any DB changes will error out.

If this is going to be a production application - where changes to the database schema are going to be made frequently, then I would suggest looking into ways of doing database migration.

Now you DO also have defined a DATABASE_VERSION definition, and this is very useful for actually doing that migration.

In your onUpgrade method you have the proper code

DROP TABLE IF EXISTS ...

However, you never actully make it here..

Every time you change your database schema, you should also increment your DATABASE_VERSION count to invoke the migration / rebuild of the table structure.

tl;dr,

private static final int DATABASE_VERSION = 2;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM