codepleb
codepleb

Reputation: 10571

"column '_id' does not exist" even if it does

EDIT: The title from before was from a draft, sorry.

I know that there are several threads about this topic, but I didn't find a solution that works for me. I applied some tips, but the error is still there.

This is the error I get, altough I have an "_id" column:

java.lang.IllegalArgumentException: column '_id' does not exist

I'm fighting this problem since hours now, I hope someone can help me with it. The first error I get is from the line "super(context, c, flags);" in "GridViewCustomAdapter" (marked as comment).

DataSet (SQLiteOpenHelper):

public class DataSet extends SQLiteOpenHelper {

    // Database Version
    private static int DATABASE_VERSION = 1;
    // Database Name
    private static final String DATABASE_NAME = "minecraft";
    // Items table name
    private static final String TABLE_ITEMS = "items";

    // Items Table Columns names
    public static final String KEY_ID = "_id";
    public static final String KEY_MC_ID = "mc_id";
    public static final String KEY_NAME = "name";
    public static final String KEY_CATEGORY = "category";
    public static final String KEY_SUBCATEGORY = "subcategory";
    public static final String KEY_URL_EXT = "url_ext";

    private static final String[] COLUMNS = { KEY_ID, KEY_MC_ID, KEY_NAME, KEY_CATEGORY, KEY_SUBCATEGORY, KEY_URL_EXT };

    public DataSet(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }


   @Override
    public void onCreate(SQLiteDatabase db) {
        Log.d("R", "oncreate...");
        // SQL statement to create book table
        String CREATE_ITEMS_TABLE = "CREATE TABLE " + TABLE_ITEMS + " (" +
                KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                KEY_MC_ID + " TEXT," +
                KEY_NAME + " TEXT," +
                KEY_CATEGORY + " TEXT," +
                KEY_SUBCATEGORY + " TEXT," +
                KEY_URL_EXT + " TEXT )";

        // create items table
        db.execSQL(CREATE_ITEMS_TABLE);
/*
        FileInputStream fis;
        fis = getApplicationContext().openFileInput("test.txt");
        StringBuilder fileContent = new StringBuilder();

        byte[] buffer = new byte[1024];
        try {
            int n;
            while ((n = fis.read(buffer)) != -1) {
                fileContent.append(new String(buffer, 0, n));
            }
        } catch (Exception e) {

        }
*/
        //Delete
        /*SQLiteDatabase dba = this.getWritableDatabase();
        Item item = new Item(12, "Diamond Sword", "Combat", null, "C:/Users", "C:/Users/images");

        ContentValues values = new ContentValues();
        values.put(KEY_MC_ID, item.getMcId()); // get author
        values.put(KEY_CATEGORY, item.getCategory());
        values.put(KEY_SUBCATEGORY, item.getSubcategory());
        values.put(KEY_URL_EXT, item.getUrlExtension());
        values.put(KEY_IMAGE_REF, item.getImageRef());
        dba.insert(TABLE_ITEMS, null, values);

        Cursor cursor = dba.query(TABLE_ITEMS, COLUMNS, KEY_ID, new String[] {"*"}, null, null, null, null);
        if (cursor == null) {
            Log.d("Tag: ", "Error, nichts gefunden!");
        } else {
            cursor.moveToFirst();
            String p = cursor.getString(2);
            Log.d("Tag", p);
        }*/
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older items table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_ITEMS);
        // create fresh items table
        this.onCreate(db);
    }


    public Cursor getAllItems() {
        SQLiteDatabase database = this.getReadableDatabase();
        return database.query(TABLE_ITEMS, null, null, null, null, null, null, null);
    }


    public void addItem(Item item){
        // 1. get reference to writable DB
        SQLiteDatabase db = this.getWritableDatabase();

        // 2. create ContentValues to add key "column"/value
        ContentValues values = new ContentValues();
        values.put(KEY_MC_ID, item.getMcId()); // get author
        values.put(KEY_NAME, item.getName());
        values.put(KEY_CATEGORY, item.getCategory());
        values.put(KEY_SUBCATEGORY, item.getSubcategory());
        values.put(KEY_URL_EXT, item.getUrlExtension());

        // 3. insert
        //db.insert(TABLE_ITEMS, null, values);

        //TEST START
        db.insertWithOnConflict(TABLE_ITEMS,null,values,SQLiteDatabase.CONFLICT_REPLACE);
        //TEST FINISH

        // 4. close
        db.close();
    }

    public void addItemList(List<Item> list) {
        int oldVersion = this.getWritableDatabase().getVersion();
        onUpgrade(this.getWritableDatabase(), oldVersion, ++oldVersion);
        SQLiteDatabase db = this.getWritableDatabase();
        db.needUpgrade(12);
        Calendar c = Calendar.getInstance();
        Date start = c.getTime();
        Log.d("Started inserting...",start.toString());
        for (Item i : list) {
            ContentValues values = new ContentValues();
            values.put(KEY_MC_ID, i.getMcId()); // get author
            values.put(KEY_NAME, i.getName());
            values.put(KEY_CATEGORY, i.getCategory());
            values.put(KEY_SUBCATEGORY, i.getSubcategory());
            values.put(KEY_URL_EXT, i.getUrlExtension());
            //db.insert(TABLE_ITEMS, null, values);
            db.insertWithOnConflict(TABLE_ITEMS,null,values,SQLiteDatabase.CONFLICT_IGNORE);
        }
        Date end = c.getTime();
        Log.d("Finished inserting: ", end.toString());
        db.close();
    }

    public Item getItem(String mc_id){

        // 1. get reference to readable DB
        SQLiteDatabase db = this.getReadableDatabase();

        // 2. build query
        Cursor cursor =
                db.query(TABLE_ITEMS, // a. table
                        COLUMNS, // b. column names
                        KEY_MC_ID, // c. selections    OLD, FALLS ES FAILT: KEY_ID + " = ?",
                        new String[] { String.valueOf(mc_id) }, // d. selections args
                        null, // e. group by
                        null, // f. having
                        null, // g. order by
                        null); // h. limit

        // 3. if we got results get the first one
        if (cursor.moveToFirst()) {

            // 4. build book object
            Item item = new Item();
            item.setMcId(cursor.getString(1));
            item.setName(cursor.getString(2));
            item.setCategory(cursor.getString(3));
            item.setSubcategory(cursor.getString(4));
            item.setUrlExtension(cursor.getString(5));

            return item;
        }
        return null;    //Else...
    }

    public boolean containsItems() {
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor =
            db.query(TABLE_ITEMS, // a. table
                    null, // b. column names
                    null, // c. selections
                    null, // d. selections args
                    null, // e. group by
                    null, // f. having
                    null, // g. order by
                    null); // h. limit
        if (cursor.getCount() > 0) return true;
        else return false;
    }

    //public Cursor getSpecificItems(String key_mc_id, String key_nameE, String key_cat, String key_subcat, String key_url_ext) {
    public Cursor getSpecificItems(String[] selectionArgs) {
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = db.rawQuery("SELECT " + KEY_SUBCATEGORY + " FROM " + TABLE_ITEMS + " WHERE " + KEY_SUBCATEGORY + " = ?", selectionArgs);
        return cursor;
    }
}

DatabaseController:

public class DatabaseController {

    private Context context;
    private DataSet dataset;

    public static Resources resources = null;

    List<Item> itemList = new ArrayList<Item>();

    public DatabaseController(Context context) {
        this.context = context;
        this.dataset = new DataSet(context);
    }

    public void readDataAndAddToDatabase() {
        try {
            resources = context.getResources();
            InputStream is = resources.openRawResource(R.raw.database_values);
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader reader = new BufferedReader(isr);

            String input;
            while ((input = reader.readLine()) != null) {
                itemList.add(new Item(input));
            }
            dataset.addItemList(itemList);
        } catch (Exception e) {
            Log.d("Fehler!!!!!!!!!!!!!!!!!!!!!!!!", "");
            e.printStackTrace();
        }
    }

    public Cursor getSpecificItems(String[] selectionArgs) {
        return this.dataset.getSpecificItems(selectionArgs);
    }

    public boolean containsItems() {
        return dataset.containsItems();
    }

    public DataSet getDatabase() {
        return this.dataset;
    }

    public Cursor getAllItems() {
        return dataset.getAllItems();
    }
}

GridViewCustonAdapter (CursorAdapter):

public class GridViewCustomAdapter extends CursorAdapter
{
    Context context;
    private LayoutInflater mInflater;

    public GridViewCustomAdapter(Context context, Cursor c, int flags) {
        super(context, c, flags);    //The Crash seems to start from here...
        this.context = context;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        TextView content = (TextView) view.findViewById(R.id.textView);
        content.setText(cursor.getString(cursor.getColumnIndex(DataSet.KEY_NAME)));

        ImageView image = (ImageView) view.findViewById(R.id.imageView);
        image.setImageBitmap(getBitmapFromAsset(cursor.getString(cursor.getColumnIndex(DataSet.KEY_MC_ID + ".png"))));
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return mInflater.inflate(R.layout.item_layout, parent, false);
    }

    private Bitmap getBitmapFromAsset(String strName)
    {
        AssetManager assetManager = context.getAssets();
        InputStream istr = null;
        try {
            istr = assetManager.open(strName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Bitmap bitmap = BitmapFactory.decodeStream(istr);
        return bitmap;
    }
}

ItemsView (Activity):

public class ItemsView extends Activity {

    DatabaseController dbc;
    GridView gridView;
    GridViewCustomAdapter gridViewCustomAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

//        String category = savedInstanceState.getString(getString(R.string.key_category));
//        String subcategory = savedInstanceState.getString(getString(R.string.key_subcategory));
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_items_view);

        this.dbc = new DatabaseController(this);


        Cursor cursor = dbc.getSpecificItems(new String[] { "tools" });

        gridView = (GridView)findViewById(R.id.gridViewCustom);
        // Create the Custom Adapter Object
        gridViewCustomAdapter = new GridViewCustomAdapter(this, cursor, 0);
        // Set the Adapter to GridView
        gridView.setAdapter(gridViewCustomAdapter);

        // Handling touch/click Event on GridView Item
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
                String selectedItem;
                if(position%2==0)
                    selectedItem="Facebook" + " @Position: " + position;
                else
                    selectedItem="Twitter" + " @Position: " + position;
                Toast.makeText(getApplicationContext(), "Selected Item: " + selectedItem, Toast.LENGTH_SHORT).show();
            }
        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.items_view, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

activity_items_view.xml (ItemsView - Layout):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.nubage.minepedia.ItemsView">

    <GridView
        android:id="@+id/gridViewCustom"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="4dp"
        android:columnWidth="80dp"
        android:gravity="center"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth" />

</RelativeLayout>

item_layout.xml (Layout for a simple entry, that should appear multiple times in the GridView from "activity_items_view.xml":

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dp" >

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginRight="10dp"
        android:src="@drawable/ic_launcher" >
    </ImageView>

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:textSize="15sp" >
    </TextView>
</LinearLayout>

StackTrace:

08-16 09:42:50.128      914-914/com.nubage.minepedia E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.nubage.minepedia, PID: 914
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nubage.minepedia/com.nubage.minepedia.ItemsView}: java.lang.IllegalArgumentException: column '_id' does not exist
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2255)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2317)
            at android.app.ActivityThread.access$800(ActivityThread.java:143)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5070)
            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:836)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)
     Caused by: java.lang.IllegalArgumentException: column '_id' does not exist
            at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:303)
            at android.widget.CursorAdapter.init(CursorAdapter.java:172)
            at android.widget.CursorAdapter.<init>(CursorAdapter.java:149)
            at com.nubage.minepedia.GridViewCustomAdapter.<init>(GridViewCustomAdapter.java:28)
            at com.nubage.minepedia.ItemsView.onCreate(ItemsView.java:40)
            at android.app.Activity.performCreate(Activity.java:5720)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1102)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2208)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2317)
            at android.app.ActivityThread.access$800(ActivityThread.java:143)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1258)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5070)
            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:836)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)

PS: I know my code is veeeery ugly. I want to do some improvements when the basic functionality works.

Upvotes: 0

Views: 1208

Answers (2)

G. Blake Meike
G. Blake Meike

Reputation: 6715

The _id column needs to be in the cursor, not just in the table! You need to include the column in your select statement.

... and, btw, you don't actually need a _id column in the table. Most SQLite tables have an implicit column named ROWID, which is unique and integer-valued. You can, very simply, make your existing code work, by changing your queries to include the following:

SELECT ROWID as _id, ...

Upvotes: 2

CL.
CL.

Reputation: 180070

The cursor does not contain a column named _id; getSpecificItems does not return this column.

Upvotes: 1

Related Questions