How to display SQLException while insert or update operation - android

I am working with SQLite android where I am using an sqLiteDatabase.insert function to insert customers and sqLiteDatabase.update to update customers and getting the result which is always a long variable, When result is -1, I know the database operation was not successful but I want to display the actual SQLException that occurred. As the return type of these methods is long so they only print the exception in log. Is there any way to get the message of SQLException and display in Toast etc.
I tried to use try catch to catch the exception and show message but when exception occurs it doesnt go to catch block. Below is my code
public void insertData(SQLiteDatabase sqLiteDatabase, Context context, ContentValues values, DatabaseOperation dbOperation, DatabaseOperationCallback dbOperationCallback) {
JSONObject resultObj = new JSONObject();
try {
if (dbOperation != null) {
sqLiteDatabase.insert(dbOperation.getTableName(), null, values);
}
}
} catch (SQLException ex) {
ex.printStackTrace();
//showing in toast; this is not triggered
} catch (Exception ex) {
ex.printStackTrace();
//showing in toast; this is not triggered
}
}
Please see below picture for reference. Any help will be appreciated

You can use
e.printStackTrace(); // (directly to the log)
or
e.getMessage(); // returns message as a String
or others as per the Java Exception Class.
However, using the insertOrThrow method, is probably the method that you want to use.

Related

Android - JSON No value for 1 - but there is using Log

I'm stuck at trying to get a simple string from a JsonObject.
Here is the basic code. result is a JsonObject returned from an Asynctask. I've done dozens of the same way, and here it doesn't work.
Response:{"status":200}
Error: An error is thrown saying "No value for 1"
When I Log the content of the JsonObject, I get this: 200, which is what I want. For which reason could this return null when there is a value?
Edit if I use the result.has("status"); true is returned. I don't understand.
Log.e("TAG", result.get("status").toString());
try{
String status = result.getString("status");
} catch (Exception e){
e.getMessage();
}
You are getting int value in the object and you are holding in string which causes the error
You are getting int value in status
{
"status":200
}
if it is like
{
"status":"200"
}
Your code works perfectly.
Try this
Log.e("TAG", result.get("status").toString());
try{
int status = result.getInt("status");
} catch (Exception e){
e.getMessage();
}

Android SQLite Transaction, two datasources

im having doubts on how to procede with database manipulation using Begin Transaction
I have 2 data source objects: ClientDataSource and MovementsDataSource
each of theres has its own SQLitedabase object which is set with the Open() method with sets its database private Object with a Writable Database.
Now, i have to send the Records from the Movements Table to a server and then ask for the updated Clients from the same server.
Inside my class i first Send the new Movements, then if sucessful, delete all clients from the SQLite, and finally retrieve the new Updated Clients from the server and insert them into the database.
each data source has a Get() method for obtainting their respective Database Object, BUT it is in fact the same database they are operating and I am not sure of how to use the BaginTransction, Endtransaction methods to ensure data consistency
this is the code from the Async Task
#Override
protected Boolean doInBackground(String... url) {
try {
clientDataSource.open();
movementDataSource.open();
} catch (SQLException e) {
//Treat SQL Exception
}
try {
if(sendMovements()) {
clientDataSource.deleteAllClients();
}
updateDatabase(url[0]);
} catch (JSONException e) {
//Treat Json Exception
} catch (IOException e) {
//Treat IOException
}
return true;
}
i have to give one example then how begintransaction works...
public static void Insert(ArrayList<Model_CategoryMaster> categoryMasters) {
SQLiteDatabase sqldb = EGLifeStyleApplication.sqLiteDatabase;
sqldb.beginTransaction();
for (Model_CategoryMaster model : categoryMasters) {
ContentValues values = new ContentValues();
values.put(CATEGORY_ID, model.Category_Id);
values.put(CATEGORYNAME, model.CategoryName);
values.put(DESCRIPTION, model.Description);
values.put(ISACTIVE, model.IsActive);
values.put(CREATEDON, model.CreatedOn);
values.put(CREATEDBY, model.CreatedBy);
values.put(UPDATEDON, model.UpdatedOn);
values.put(UPDATEDBY, model.UpdatedBy);
values.put(ISDELETED, model.IsDeleted);
values.put(DELETEDON, model.DeletedOn);
values.put(DELETEDBY, model.DeletedBy);
values.put(PK_CATEGORYMASTER, model.PK_CategoryMaster);
if (!CommonMethod.CheckIsDataAlreadyInDBorNot(Table_Name,
CATEGORY_ID, model.Category_Id)) {
sqldb.insert(Table_Name, null, values);
} else {
sqldb.update(Table_Name, values, "Category_Id=?",
new String[] { model.Category_Id });
}
}
sqldb.setTransactionSuccessful();
sqldb.endTransaction();
}// End insert method
begin transaction means data will get arraylist then db will open one time and sql.begintansaction() use to get faster database operation.because db is not open or close more times.

unable to open database file (code 14) beginTransactionUnchecked

I have search through SO and google but doesn't seem fit into my case.
My application randomly gives me this exception from multiple user logs, which never happen while I test it in the emulator nor my device.(I am running on Galaxy tab2 10.1 ,android OS 4.1.1.)
I tested it can be run successfully from development.The required android manifest permissions are in place.
Below are my codes and stack trace
stacktrace :
android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)
android.database.sqlite.SQLiteConnection.nativeExecute(Native Method)
android.database.sqlite.SQLiteConnection.execute(SQLiteConnection.java:678)
android.database.sqlite.SQLiteSession.beginTransactionUnchecked(SQLiteSession.java:323)
android.database.sqlite.SQLiteSession.beginTransaction(SQLiteSession.java:298)
android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:505)
android.database.sqlite.SQLiteDatabase.beginTransaction(SQLiteDatabase.java:416)
com.framework.dataaccess.GenericDAO.start(GenericDAO.java:78)
Below is my singleton that instantiate SQLitedatabase
protected static GenericDAO getInstance(Context ctx, String sql) {
if (instance == null) {
try {
instance = new GenericDAO(ctx, sql);
}
catch (Exception e) { e.printStackTrace(); }
}
if(db == null || !db.isOpen()){
try {
db = instance.getWritableDatabase();
}
catch (Exception e) { e.printStackTrace(); }
}
return instance;
}
and for Insertion, delete or update operation I would put in these start() and commit().
public void start() throws Exception{
try{
db.beginTransaction();
}catch(Exception e){
e.printStackTrace();
throw e;
}
}
public void commit() throws Exception{
try{
db.setTransactionSuccessful();
}
catch(Exception e){
e.printStackTrace();
throw e;
}
finally{
db.endTransaction();
}
}
public Cursor select(String table, String[] columns, String criteriaColValue){
return db.query(true, table, columns, criteriaColValue, null, null, null, null, null);
}
My code throws the exception from the dao select below. Which does not call the 'start()' method.
public ArrayList<Obj> getObjList(){
ChildDao dao = null;
Cursor cursor = null;
ArrayList<Obj> list = new ArrayList<Obj>();
try{
dao = new childDao(context);
cursor = dao.select(TABLE_NAME, columns, Criterea );
if(cursor!=null && cursor.moveToFirst()){
do{
list.add(myObjs);
} while(cursor.moveToNext());
}
}catch(Exception ex){
ex.printStackTrace();
}
finally{
if(cursor!=null)cursor.close();
}
return list;
}
I have no idea how the error hit and not able to reproduce it from development environment. Can anyone give me a guide where to look into ?
Thanks in advance.
This may be a little late, but hope this can give a clue for whoever gets this problem. I also had a similar hard to reproduce exception:
unable to open database file (code 14)
android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14)
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:845)
It could be not because of database but has to do with extra data/files allocation somewhere in an application. In my case it was bad SoundPool code. Here are the details:
java.lang.RuntimeException: Could not read input channel file descriptors from parcel

Debugging a OperationApplicationException insert failed

I am going to try to simplify this situation as much as possible.
Observe the following code:
//...
ArrayList<ContentProviderOperation> batch = Lists.newArrayList();
while(recordsToProcess){
//... Grabbing data
//... built a ContentProviderOperation variable named operation
batch.add(operation);
//... setting recordsToProcess to true or false
}
try {
mContext.getContentResolver().applyBatch(Contract.CONTENT_AUTHORITY, batch);
} catch (RemoteException e) {
throw new RuntimeException("Problem applying batch operation", e);
} catch (OperationApplicationException e) {
throw new RuntimeException("Problem applying batch operation", e);
}
}
During this process, an OperationApplicationException is thrown, which looks like:
... Problem applying batch operation
... android.content.OperationApplicationException: insert failed
... Stack Trace ....
I understand that this exception is "thrown if either the insert fails or if the number of rows affected didn't match the expected count" and/or "Thrown when an application of a ContentProviderOperation fails due the specified constraints."
My database schema has hardly any constraints and the data going in the operation is valid.
Is there any way to get more information to why the exception is thrown? What constraint failed? etc...?
For debugging I would start with something like this
{
.........
int i = 0;
for (ContentProviderOperation op : ops) {
applySingle(WorkoutProvider.AUTHORITY, op);
Log.e(getTag(), Integer.toString(i));
i++;
}
}
protected synchronized void applySingle(String authority, ContentProviderOperation op) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ops.add(op);
try {
App.getInstance().getContentResolver().applyBatch(authority, ops);
} catch (RemoteException e) {
Log.e(getTag(), "Error updating workout id to server's", e);
e.printStackTrace();
} catch (OperationApplicationException e) {
Log.e(getTag(), "Error updating workout id to server's", e);
e.printStackTrace();
}
}
Then I would recommend debugging before that for loop and taking a look at what operation failed.

Ormlite ObjectCache returning old data

I'm using Ormlite on Android and with the ObjectCache enabled, I get old data back after updating the table with an UpdateBuilder and a ColumnExpression. I have read through the doc and it does not warn against using the UpdateBuilder with the cache enabled.
The settings table should have just 1-5ish rows max. The updateColumnExpression seems like an easy way to allow only one of the rows to be true.
Is this the expected behavior?
public void setActiveSetting(String id)
{
try {
UpdateBuilder<Settings, Integer> updateBuilder2 = getHelper().getSettingsDao().updateBuilder();
updateBuilder2.updateColumnExpression("active", "id = " + id );
updateBuilder2.update();
} catch (SQLException e){
e.printStackTrace();
}
}
And this is the call that returns the outdated data:
public List<Settings> getSettings()
{
List<Settings> settings = null;
try {
settings = getHelper().getSettingsDao().queryForAll();
} catch (SQLException e) {
e.printStackTrace();
}
return settings;
}
And the settings DAO:
public Dao<Settings, Integer> getSettingsDao()
{
if (null == settingsDao) {
try {
settingsDao = getDao(Settings.class);
settingsDao.setObjectCache(true);
} catch (java.sql.SQLException e) {
e.printStackTrace();
}
}
return settingsDao;
}
Disabling the ObjectCache does return the correct data, but this data is fetched quite frequently, so I'd like to keep it.
Thanks
Is this the expected behavior?
Unfortunately, yes. If you had updated the object using dao.update(...); then the cache would know that the object needed to be refreshed. By using the UpdateBuilder to make mass changes to the table, there is no way for the cache to know which objects were affected.
You will need to clear the cache after your call to the UpdateBuilder finishes.

Categories

Resources