Can someone tell me, why this code:
Boolean done = db.delete(ACCOUNTS_TABLE, KEY_ROWID, getIds(accounts)) > 0;
return this exception?
05-08 10:09:36.074: E/AndroidRuntime(1955): java.lang.NullPointerException
function return array of strings, so everything should be OK
Solution
before delete a called close() on db
But now it return this exception:
android.database.sqlite.SQLiteBindOrColumnIndexOutOfRangeException: bind or column index out of range: handle 0x1eef920
If that is indeed the problematic line referred to in the exception, it's almost certainly because db is a null reference, or possibly because getIds throws the exception.
It's a little difficult to tell without more information but, as a start, I'd be putting in something to dump the db variable out, either beforehaned or as part of an try/catch block around the call.
Related
I got an exception in my code.
10-10 22:05:33.866 5725 5725 E AndroidRuntime: Caused by: net.sqlcipher.database.SQLiteDiskIOException: error code 10: disk I/O error
10-10 22:05:33.866 5725 5725 E AndroidRuntime: at net.sqlcipher.database.SQLiteStatement.native_execute(Native Method)
10-10 22:05:33.866 5725 5725 E AndroidRuntime: at net.sqlcipher.database.SQLiteStatement.execute(SQLiteStatement.java:58)
10-10 22:05:33.866 5725 5725 E AndroidRuntime: at net.sqlcipher.database.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:2074)
This has only happened once (so far) among thousands of successful inserts and selects, so I suspect there is some kind of race condition between different threads in the same process trying to access the same database.
The actual code is unimportant, this is just a plain insert of a new record, and the on conflict parameter is saying to ignore any conflict:
ContentValues values = new ContentValues();
// values.put(); calls go here, nothing strange about the data
db.insertWithOnConflict("Sample", null, values, SQLiteDatabase.CONFLICT_IGNORE);
Architectually I have a singleton object in my Service encapsulating a single continuously open connection to the database with a cache sitting in front of it. Multiple threads call the object from different places in the Service to insert data, these are typically listeners which are logging things such as GPS position, battery state, etc. Reading typically comes from the cache and does not hit the database.
My first thought was that perhaps I need to synchronize the class through which database access flow (it smells like two different threads might be trying to insert at almost exactly the same time, which in practice would happen rarely), but this answer seems to be saying that I should be able to do this with no problem. "Inserts, updates, deletes and reads are generally OK from multiple threads" Of note the exception says "I/O error" not "database locked".
Update: I added logcat traces and exception catching around every database access. After that I got two more exceptions. In both cases only a single database access was in progress. Both were simple inserts. The first one threw an exception 1.2 seconds after the insertion began, which seems unbelievably high. The second only took 38ms which looks to be about average.
The issues is not running out of storage: I have 27GB free. I have a hard time believing it is an issue with the flash either, as I am not seeing any other errors with write to it. I have also not seen any issues like this with an older app that uses the same SQLCipher library but which closes the database after each insert.
Update 2: In the exception handler I added code to immediately retry the insert, and so far I have not received a second exception at this point:
try {
ret = db.insertWithOnConflict("Sample", null, values, SQLiteDatabase.CONFLICT_IGNORE);
} catch (Exception e) {
Log.d(logtag,"exception:"+e);
try {
ret = db.insertWithOnConflict("Sample", null, values, SQLiteDatabase.CONFLICT_IGNORE);
} catch (Exception e1) {
Log.d(logtag,"exception2:"+e1);
}
return 0;
}
Do you know how to prevent exception when using
Synchronization synchronization = query.findAllSorted("endDate", Sort.DESCENDING).first();
if database is empty?
I'm trying to get the last synchronization in Synchronization table. But if there isn't any record in table, I'm catching an exception.
What's the best way to do that ?
Thank you.
You can do the following:
RealmResults<Synchronization> results = query.findAllSorted("endDate", Sort.DESCENDING);
Synchronization obj = (result.size() > 0) ? result.first() : null;
Although I do agree that it could be a bit easier.
I'm getting an NullPointerException when I insert values into to my SQLite table on Android and I don't understand why. I'm testing ContentValues and the database instance for null.
This is the insertion code:
public void insertOrIgnore(ContentValues values) {
SQLiteDatabase db = this.dbHelper.getWritableDatabase();
try {
//I added these null value checks to stop NPE, but doesn't help.
if (values != null && db != null) {
db.insertWithOnConflict(TABLE, null, values, SQLiteDatabase.CONFLICT_IGNORE);
}
} catch (SQLiteException e) {
} finally {
if (db != null) {
db.close();
}
}
}
where
public static final String TABLE = "albums";
Most of the time this code works with the data added to the database as expected. However, it sometimes and rarely generates the below error. The stack trace is from ACRA and I have not been able to isolate under what conditions this error occurs. I'm looking for pointers as to why this happens and what the conditions are. My knowledge of SQLite is beginner level.
java.lang.NullPointerException
at android.database.sqlite.SQLiteStatement.releaseAndUnlock(SQLiteStatement.java:290)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:96)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:2025)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1965)
at android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:690)
at android.database.sqlite.SQLiteDatabase.beginTransactionNonExclusive(SQLiteDatabase.java:605)
at android.database.sqlite.SQLiteStatement.acquireAndLock(SQLiteStatement.java:247)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:112)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1844)
at com.mydomain.myapp.albums.AlbumsData.insertOrIgnore(AlbumsData.java:89)
Line 89 is the db.insertWithOnConflict(...) call shown above.
I'm not looking for an answer with complete code necessarily but rather a pointer and explanation as to what's going wrong so I can begin to fix it myself.
EDIT:
The stack trace shows the NPE originates from line 290 of SQLiteStatement (v 4.03):
setNativeHandle(mDatabase.mNativeHandle);
So it seems the database instance is null. How can it become null during a transaction when I tested for null at the beginning of the transaction?
As mentioned here SQLiteDatabase close() function causing NullPointerException when multiple threads
The reason for your bug could be that you close the database at some point. Probably concurrently while the task that fails was not finished.
I've followed the stacktrace a bit and this is what roughly happens:
AlbumsData.insertOrIgnore(AlbumsData.java:89)
You call insertWithOnConflict, which builds the resulting sql string ("INSERT OR IGNORE INTO...") then wraps that together with the values from your ContentValues into a SQLiteStatement.
SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1844) - The resulting statement is to be executed now
SQLiteStatement.executeInsert(SQLiteStatement.java:112) - before the actual insert can happen, the database needs to acquire a lock.
SQLiteStatement.acquireAndLock(SQLiteStatement.java:247) - some checks happen here, the database object is as far as I can see not null at that point. Code decides that it has to start a transaction. The database object itself is as far as I can see not locked at that point.
SQLiteDatabase.beginTransactionNonExclusive(SQLiteDatabase.java:605) - just forwarding
SQLiteDatabase.beginTransaction(SQLiteDatabase.java:690) - after some checks (not sure if database has to exist here) it will try to execute execSQL("BEGIN IMMEDIATE;")
SQLiteDatabase.execSQL(SQLiteDatabase.java:1965) - just forward
SQLiteDatabase.executeSql(SQLiteDatabase.java:2025) - builds another SQLiteStatement out of "BEGIN IMMEDIATE;. This one should be executed now
SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:96) - starts with checking the database lock, this seems to be okay and the database should not be null here. The statement is then executed and finally the database is to be unlocked again.
SQLiteStatement.releaseAndUnlock(SQLiteStatement.java:290) - cleans up some stuff and in the end fails with NPE because the database is null.
Line numbers don't match so there are probably vendor modifications / additions in that code.
As you can see, the code crashes before actually using the data you supplied. It was about to do
BEGIN TRANSACTION IMMEDIATE; -- crash
INSERT INTO table (...) VALUES (...);
-- (end transaction)
That makes it in my opinion a framework bug. The database object that is internally handled there should not be able to be null somewhere down the line, especially when it seems that it was not null further up in the stack.
I also think that it is possible that another hidden exception could be the root cause for this. There are a lot of try { /* do stuff */ } finally { /* clean up */ } blocks within the code and the finally part will be executed even if the try part throws an exception. Now the finally block could cause another exception and the result is AFAIK that the original exception is replaced by the new exception from the finally block.
Especially executeUpdateDelete() is like
try {
acquireAndLock(WRITE);
// actual statement execution
} finally {
releaseAndUnlock();
}
if the database is closed at that point, acquireAndLock or any code in the try part could fail and that could leave the database object at null which causes releaseAndUnlock to fail again. You should get the same stacktrace.
Apart from that, don't do empty catch blocks like catch (SQLiteException e) { /* empty */ }. Log them with ACRA if possible / you don't do that already.
This NPE appears to be from a custom ROM as the Android source code is pointing to different Methods than the ones you receive in the LogCat. What I do for such cases is that: if the rate of these exceptions is very rare, I ignore them as it is difficult to know what custom ROM is running on the phone and more difficult to get the source code of this custom ROM to know where the problem is.
Not many users are using custom ROMs, so if you extensively tested your App on different phones with different SDKs and the rate of the Exceptions you get is not that significant, you can ignore them. Otherwise, you can take a shoot in the dark and speculate what can be in this custom ROM that is causing NPE (personally, I think it is not worth the effort).
In my application, I use SQLiteOpenHelper class and it has insertOrThrow method. I want to learn that will this method close my connection before throw an exception? And it is written on definition of method that "the row ID of the newly inserted row, or -1 if an error occurred "
When throw an exception how it has a return value? Something is wrong. Explanation or throw ?
This is how I use InsertOrThrow.
I want to know when I declare throws Exception to my method, is it necessary to use try-catch (If I don't have any special thing to do in catch like my exp.)?
public long insert(ContentValues cv) throws Exception {
try
{
long rowId = getWritableDatabase().insertOrThrow(_tableName, null, cv);
return rowId;
}
catch (Exception ex) {
throw ex;
}
finally{
Close();
}
}
It depends; if this.Close() can throw an exception, then it still needs to be declared as being thrown, or caught. Often times this is wrapped up in a small utility method.
It's not mandatory to use a catch, you can simply try/finally.
Regarding return values: methods that exit due to an exception don't have a return value.
Exceptions should encapsulate enough information to either:
allow the caller to do something useful with the exception, e.g., retry the operation, or
assist the developer in understanding the problem and lead him/her to a resolution.
I'd encourage you to follow standard Java naming conventions to avoid confusing readers of your code: non-final variables should begin with a lower-case letter. Method names should also begin with lower-case letters.
Also, you do not need to preface methods (or variables) with this when there is no need to disambiguate the property you're accessing.
When throw an exception how it has a return value? Something is wrong.
Yes, you're right. The documentation seems wrong.
insertOrThrow doesn't return -1 , instead, it will throw SQLException if the query failed. There's a another method called insert which would return -1 if the query failed, and newly created rowID if success.
i have a try/catch in a function that returns a value. if all goes well the return statement in the try block works fine. but what am i supposed to do if theres an exception? what do i return in the catch and finally blocks? the return statement has to be there or the code doesnt compile.
edit: in 1 function i connect to a URL, read a file, and return a string. in another function i open an image from the internet and return a bitmap. so in both of these cases, what am i supposed to have in the return statement at the catch and finally blocks?
One of the following:
Return a special value that indicates an error to the calling code.
Return a default value (depending on your context, there may not be a good one).
Don't catch the exception, instead add a throws to the header.
Catch the exception, do the cleanup, and rethrow the exception.
In general, there's no escaping the fact that the function can error out. The calling code must either be notified of that, or the function must effectively swallow an error and pretend nothing bad happened; that involves returning something. The specifics depend on your context...
The value you return should be able to represent an error, for example, null should mean the function didn't work. So, in the catch block, the function would return null, for example. In the finally block, you should free any resource you used (for example, close any files you opened, etc).
You put those things in the finally block because it's guaranteed that it will be ran sometime, even if the code in your catch block throws an unhandled exception or anything. And it will also run if the function worked just as wanted.
Use return null; this statement outside your try/catch block. If the things work, your try block will execute and will return , if it fails because of exception, it will be caught and you will see error.