3

I'm having a problem using the ormlite-android-sqlcipher-4:48 library and SQLCipher.for.Android.v3.1.0 to perform the encryption of SQLite file. I believe that the error happens because I'm using ForeignCollectionField with the property 'eager = false' when true not get an error. I need not always false property to reload the object. Below is the mapping and error stack.

@ForeignCollectionField(eager = false, orderColumnName = CartaoSus.PRINCIPAL, orderAscending = false)
private ForeignCollection cartaoSus;

01-15 13:03:36.055: E/Cursor(3041): Finalizing a Cursor that has not been deactivated or closed. database = /data/data/br.gov.prodemge.sres/databases/sres.db, table = null, query = SELECT * FROM TBCARTAOSUS WHERE ID_USUARIOSUS = ? ORDER BY PRINCIPAL DESC
01-15 13:03:36.055: E/Cursor(3041): net.sqlcipher.database.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
01-15 13:03:36.055: E/Cursor(3041): at net.sqlcipher.database.SQLiteCursor.(SQLiteCursor.java:217)
01-15 13:03:36.055: E/Cursor(3041): at net.sqlcipher.database.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53)
01-15 13:03:36.055: E/Cursor(3041): at net.sqlcipher.database.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1447)
01-15 13:03:36.055: E/Cursor(3041): at net.sqlcipher.database.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1416)
01-15 13:03:36.055: E/Cursor(3041): at com.j256.ormlite.sqlcipher.android.compat.BasicApiCompatibility.rawQuery(BasicApiCompatibility.java:16)
01-15 13:03:36.055: E/Cursor(3041): at com.j256.ormlite.sqlcipher.android.AndroidCompiledStatement.getCursor(AndroidCompiledStatement.java:180)
01-15 13:03:36.055: E/Cursor(3041): at com.j256.ormlite.sqlcipher.android.AndroidCompiledStatement.runQuery(AndroidCompiledStatement.java:65)
01-15 13:03:36.055: E/Cursor(3041): at com.j256.ormlite.stmt.SelectIterator.(SelectIterator.java:55)
01-15 13:03:36.055: E/Cursor(3041): at com.j256.ormlite.stmt.StatementExecutor.buildIterator(StatementExecutor.java:247)
01-15 13:03:36.055: E/Cursor(3041): at com.j256.ormlite.dao.BaseDaoImpl.createIterator(BaseDaoImpl.java:964)
01-15 13:03:36.055: E/Cursor(3041): at com.j256.ormlite.dao.BaseDaoImpl.iterator(BaseDaoImpl.java:533)
01-15 13:03:36.055: E/Cursor(3041): at com.j256.ormlite.dao.LazyForeignCollection.seperateIteratorThrow(LazyForeignCollection.java:313)
01-15 13:03:36.055: E/Cursor(3041): at com.j256.ormlite.dao.LazyForeignCollection.iteratorThrow(LazyForeignCollection.java:71)
01-15 13:03:36.055: E/Cursor(3041): at com.j256.ormlite.dao.LazyForeignCollection.closeableIterator(LazyForeignCollection.java:60)
01-15 13:03:36.055: E/Cursor(3041): at com.j256.ormlite.dao.LazyForeignCollection.iterator(LazyForeignCollection.java:47)
01-15 13:03:36.055: E/Cursor(3041): at com.j256.ormlite.dao.LazyForeignCollection.iterator(LazyForeignCollection.java:28)
01-15 13:03:36.055: E/Cursor(3041): at br.gov.prodemge.sres.model.UsuarioSUS.getCodigoNumeroCartaoPrincipal(UsuarioSUS.java:791)
01-15 13:03:36.055: E/Cursor(3041): at br.gov.prodemge.sres.components.listview.AdapterListViewResultadoPesquisaCidadaoItem.getView(AdapterListViewResultadoPesquisaCidadaoItem.java:69)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.AbsListView.obtainView(AbsListView.java:2012)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.ListView.makeAndAddView(ListView.java:1772)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.ListView.fillDown(ListView.java:672)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.ListView.fillFromTop(ListView.java:732)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.ListView.layoutChildren(ListView.java:1625)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.AbsListView.onLayout(AbsListView.java:1863)
01-15 13:03:36.055: E/Cursor(3041): at android.view.View.layout(View.java:11278)
01-15 13:03:36.055: E/Cursor(3041): at android.view.ViewGroup.layout(ViewGroup.java:4224)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
01-15 13:03:36.055: E/Cursor(3041): at android.view.View.layout(View.java:11278)
01-15 13:03:36.055: E/Cursor(3041): at android.view.ViewGroup.layout(ViewGroup.java:4224)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
01-15 13:03:36.055: E/Cursor(3041): at android.view.View.layout(View.java:11278)
01-15 13:03:36.055: E/Cursor(3041): at android.view.ViewGroup.layout(ViewGroup.java:4224)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.LinearLayout.onLayout(LinearLayout.java:1399)
01-15 13:03:36.055: E/Cursor(3041): at android.view.View.layout(View.java:11278)
01-15 13:03:36.055: E/Cursor(3041): at android.view.ViewGroup.layout(ViewGroup.java:4224)
01-15 13:03:36.055: E/Cursor(3041): at android.widget.FrameLayout.onLayout(FrameLayout.java:431)
01-15 13:03:36.055: E/Cursor(3041): at android.view.View.layout(View.java:11278)
01-15 13:03:36.055: E/Cursor(3041): at android.view.ViewGroup.layout(ViewGroup.java:4224)
01-15 13:03:36.055: E/Cursor(3041): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1489)
01-15 13:03:36.055: E/Cursor(3041): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442)
01-15 13:03:36.055: E/Cursor(3041): at android.os.Handler.dispatchMessage(Handler.java:99)
01-15 13:03:36.055: E/Cursor(3041): at android.os.Looper.loop(Looper.java:137)
01-15 13:03:36.055: E/Cursor(3041): at android.app.ActivityThread.main(ActivityThread.java:4424)
01-15 13:03:36.055: E/Cursor(3041): at java.lang.reflect.Method.invokeNative(Native Method)
01-15 13:03:36.055: E/Cursor(3041): at java.lang.reflect.Method.invoke(Method.java:511)
01-15 13:03:36.055: E/Cursor(3041): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-15 13:03:36.055: E/Cursor(3041): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-15 13:03:36.055: E/Cursor(3041): at dalvik.system.NativeStart.main(Native Method)
tyczj
  • 71,600
  • 54
  • 194
  • 296

1 Answers1

0

When you work with a foreign collections in ORMLite the cursor doesn't get closed automatically in some cases. Form the official ORMLite doc:

WARNING: The underlying results object will only be closed if you page all the way to the end of the iterator using the for() loop or if you call Closeable.close() directly. You can also call the closeLastIterator() if you are not iterating across this DAO in multiple threads.

It is quite easy to break a for-loop and it will leave cursor object opened. For example imagine the following method with a loop through the foreign collection:

public ListItem getSpecificItem(ForeignCollection<ListItem> list) {
    for (ListItem item : list) {
        if (item.isSpecificOne())
            return item;
    }
}

This way the for-loop will break before it reaches the end and cursor object won't be closed. You should either call ForeignCollection.closeLastIterator() before breaking the loop or reorganize the code to let the loop go till the end.