Primary key not returned correctly in sqlite database

I am creating an app to understand sqlite database.

enter image description here

Whenever I click add button the name would be added in sqlite database

btnAdd.setOnClickListener(v -> {
            DBHelper helper=new DBHelper(MainActivity.this, null, null, 1);
            EmployeeData data=new EmployeeData(1, etName.getText().toString());
            int id=helper.add(data);
            data.setId(id);
            Toast.makeText(MainActivity.this, Integer.toString(id), Toast.LENGTH_SHORT).show();
        });

EmployeeData just contains constructor and getters and setters for the arguments.

DBHelper code:

public int add(EmployeeData data){
        SQLiteDatabase db=getWritableDatabase();
        ContentValues cv=new ContentValues();
        cv.put(NAME, data.getName());
        db.insert(TABLE_NAME, null, cv);
        String sql="SELECT * FROM "+TABLE_NAME+" WHERE "+NAME+" = "+"'"+data.getName()+"'";
        Cursor c=db.rawQuery(sql, null);
        int id;
        if (c.moveToFirst()) {
            id = c.getInt(c.getColumnIndex(ID));
        }else {
            id=-1;
        }
        c.close();
        db.close();
        return id;
    }

Consider I am entering “Aditya” in the edit text, I am getting a toast message of 1.

But when I change the name as “Adity” I am still getting a toast message of 1.

Why isn’t primary key of second record changing?

I even tried adding AUTOINCREMENT but it doesn’t work.

What is the problem?

Btw the 1 in employee data constructor has no relation to the primary key

Database creation:

@Override
    public void onCreate(SQLiteDatabase db) {
        String sql="CREATE TABLE "+TABLE_NAME+" ( "+ID+" INTEGER PRIMARY KEY, "+NAME+" VARCHAR2(25))";
        db.execSQL(sql);
    }

Answer

If you look at the insert method. It returns the id, as a long, of the inserted row else -1 if the row was not inserted.

  • In theory the id can be a long, as such it is recommended that long instead of int is used.

Assuming that the id column is an alias of the rowid.

  • according to your CREATE SQL it is.

Your code could be the simpler :-

public long add(EmployeeData data){
    long id;
    SQLiteDatabase db=getWritableDatabase();
    ContentValues cv=new ContentValues();
    cv.put(NAME, data.getName());
    id = db.insert(TABLE_NAME, null, cv);
    db.close();
    return id;
}

However, it is inefficient to close the database –

  • close itself is not that inefficient, the inefficiency is opening the database again which is relatively expensive.
  • This q/a has some details regarding this Best place to close database connection

I would suggest the even simpler :-

public long add(EmployeeData data) {
    SQLiteDatabase db=getWritableDatabase();
    ContentValues cv=new ContentValues();
    cv.put(NAME, data.getName());
    return db.insert(TABLE_NAME, null, cv);
}

Example

Here’s the code of an example based upon your code (using the logcat as well as the toast) :-

The DatabaseHelper DBHelper

public class DBHelper extends SQLiteOpenHelper {

    public static String DBNAME = "MYDB";
    public static int DBVERSION = 1;
    public static String TABLE_NAME = "mytable";
    public static String ID = "_id";
    public static String NAME = "_name";

    public DBHelper(@Nullable Context context) {
        super(context, DBNAME, null, DBVERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql="CREATE TABLE "+TABLE_NAME+" ( "+ID+" INTEGER PRIMARY KEY, "+NAME+" VARCHAR2(25))";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    }

    public long add(EmployeeData data) {
        SQLiteDatabase db=getWritableDatabase();
        ContentValues cv=new ContentValues();
        cv.put(NAME, data.getName());
        return db.insert(TABLE_NAME, null, cv);
    }
}

The invoking Activity

  • the onClickListener has been replaced with direct invocation of 2 inserts
  • in addition to using the toast the log has been used to record the id’s inserted

:-

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DBHelper helper=new DBHelper(MainActivity.this);
        EmployeeData data=new EmployeeData(1, "TestIt");
        long id=helper.add(data);
        data.setId(id);
        Toast.makeText(MainActivity.this, Long.toString(id), Toast.LENGTH_SHORT).show();
        Log.d("ADDEMP","ID of Employee was " + id);

        data.setName("TestAnother");
        data.setId(id =helper.add(data));
        Toast.makeText(this,Long.toString(id),Toast.LENGTH_SHORT).show();
        Log.d("ADDEMP","ID of Employee was " + id);
    }
}

The EmployeeData class (guessed) :-

public class EmployeeData {
    long id;
    String name;
    int something;

    EmployeeData(int something, String name) {
        this.id = -1;
        this.name = name;
        this.something = something;
    }

    public long getId() {
        return id;
    }

    public int getSomething() {
        return something;
    }

    public String getName() {
        return name;
    }

    public void setId(long id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setSomething(int something) {
        this.something = something;
    }
}

Results

When the above is run after ensuring that no database already exists (the App is uninstalled from the test device (Emulator) via settings)

  • Uninstalling the App deletes the database and should be undertaken if any changes to the schema have been made, otherwise those changes will not be applied (not entirely true as you could introduce code to make such changes).

The LogCat shows :-

D/ADDEMP: ID of Employee was 1
D/ADDEMP: ID of Employee was 2

If run a second time the LogCat shows :-

D/ADDEMP: ID of Employee was 3
D/ADDEMP: ID of Employee was 4


Additional as per comments

As per the comments you issue was that you were inadvertently using a temporary database/in_memory database and rows were being added to a new database each time and hence the id was always 1.

The following are some suggested changes (see comments in the code) based upon your GITHUB code.

DBHelper

public class DBHelper extends SQLiteOpenHelper {

    public static final String DB_NAME = "adityya425"; //<<<<<<<<<< SUGGESTED ADDITION
    public static final int DB_VERSION = 1; //<<<<<<<<<< ADDED
    final String TABLE_NAME="Employee";
    final String ID="_id";
    final String NAME="name";

    /*

    <<<<<<<<<< Replaced constructor with simpler to use (only requires the Context to be passed to the helper)
    public DBHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, null, version);
    }
     */
    public  DBHelper(Context context) {
        super(context,DB_NAME,null,DB_VERSION); //<<<<<<<<<< only context is passed
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql="CREATE TABLE "+TABLE_NAME+" ( "+ID+" INTEGER PRIMARY KEY, "+NAME+" VARCHAR2(25))";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public long add(EmployeeData data){
        long id;
        SQLiteDatabase db=getWritableDatabase();
        ContentValues cv=new ContentValues();
        cv.put(NAME, data.getName());
        id=db.insert(TABLE_NAME, null, cv);
        //String sql="SELECT * FROM "+TABLE_NAME+" WHERE "+NAME+" = "+"'"+data.getName()+"'";
        //Cursor c=db.rawQuery(sql, null);

//        if (c.moveToFirst()) {
//            id = c.getInt(c.getColumnIndex(ID));
//        }else {
//            id=-1;
//        }
        return id;
    }

    /*
        <<<<<<<<<< NOT REQUIRED optional extra that will output all the existing rows to the log
        e.g.
        2021-03-23 18:21:01.749 4963-4963/a.a.adityya425 D/CURSORINFO: ID = 1 NAME = harry
        2021-03-23 18:21:01.749 4963-4963/a.a.adityya425 D/CURSORINFO: ID = 2 NAME = bert
     */
    public void showALL(Context context) {
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor csr = db.query(TABLE_NAME,null,null,null,null,null,null);
        while (csr.moveToNext()) {
            Log.d("CURSORINFO","ID = " + csr.getLong(csr.getColumnIndex(ID)) + " NAME = " + csr.getString(csr.getColumnIndex(NAME)));
        }
        csr.close();
    }
}

MainActivity

public class MainActivity extends AppCompatActivity {
    EditText etName;
    Button btnAdd;
    DBHelper helper; //<<<<<<<<<< Single helper with class scope

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        helper = new DBHelper(this); //<<<<<<<< Instantiate Helper

        etName=findViewById(R.id.etName);
        btnAdd=findViewById(R.id.btnAdd);

        btnAdd.setOnClickListener(v -> {
            //DBHelper helper=new DBHelper(MainActivity.this, "mydb", null, 1); <<<<<<<<<< REMOVED (no need)
            EmployeeData data=new EmployeeData(etName.getText().toString());
            long id=helper.add(data);
            data.setId(id);
            Toast.makeText(MainActivity.this, Long.toString(id), Toast.LENGTH_SHORT).show();
            helper.showALL(MainActivity.this); //<<<<<<<<<< Optional (logcat is available longer)
        });
    }
}

Testing

The App was run and 3 Employees were added (Fred, Mary and Susan). The logcat shows :-

2021-03-23 18:40:15.495 5642-5642/a.a.adityya425 D/CURSORINFO: ID = 1 NAME = Fred

2021-03-23 18:40:22.964 5642-5642/a.a.adityya425 D/CURSORINFO: ID = 1 NAME = Fred
2021-03-23 18:40:22.964 5642-5642/a.a.adityya425 D/CURSORINFO: ID = 2 NAME = Mary

2021-03-23 18:40:29.643 5642-5642/a.a.adityya425 D/CURSORINFO: ID = 1 NAME = Fred
2021-03-23 18:40:29.643 5642-5642/a.a.adityya425 D/CURSORINFO: ID = 2 NAME = Mary
2021-03-23 18:40:29.643 5642-5642/a.a.adityya425 D/CURSORINFO: ID = 3 NAME = Susan