So I basically parse a JSON and store ~3000 rows (no multimedia) in the greendao generated table and I am getting the above error from while querying data in this function:
@Synchronized
private fun checkGroupVisibility(
dependencyList: ArrayList<Long>,
dependencyType: String,
mInspectionId: Long,
isFromPhilosophyFlow: Boolean,
daoSession: DaoSession?,
string: String?
): Boolean {
var show = true
// Log.d("TAG", "checkGroupVisibility: lock testing 2"+string)
if (!DataSanityUtils.isListEmpty(dependencyList)) {
//check further in database if dependency question is answered
val inspectionReportCarParList:List<InspectionReportCarPart>? = daoSession?.inspectionReportCarPartDao?.queryBuilder()
?.where(InspectionReportCarPartDao.Properties.InspectionID.eq(mInspectionId))
?.where(InspectionReportCarPartDao.Properties.QuestionId.`in`(dependencyList))
?.list()
val inspectionReportCheckpointList:List<InspectionReportCheckpoint>? = daoSession?.inspectionReportCheckpointDao?.queryBuilder()
?.where(InspectionReportCheckpointDao.Properties.InspectionID.eq(mInspectionId))
?.where(InspectionReportCheckpointDao.Properties.ReportCheckpointVerdict.eq(CommonConstants.CHECKPOINT_VERDICT_NOT_OKAY))
?.list()
for (checkPointId in dependencyList) {
if (!isFromPhilosophyFlow && philosophyIdCheckPointMap.containsKey(checkPointId)) {
show = false
break
}
val isCarPartFound:InspectionReportCarPart?= inspectionReportCarParList?.find {
it.questionId==checkPointId
}
if (isCarPartFound==null) {
val isFound= inspectionReportCheckpointList?.find {
it.optionId==checkPointId
}
if (isFound == null) {
show = false
if (CommonConstants.DEPENDENCY_RELATION_AND.equals(
dependencyType,
ignoreCase = true
)
) {
break
}
} else if (CommonConstants.DEPENDENCY_RELATION_OR.equals(
dependencyType,
ignoreCase = true
)
) {
show = true
break
}
} else if (CommonConstants.DEPENDENCY_RELATION_OR.equals(
dependencyType,
ignoreCase = true
)
) {
show = true
break
}
}
}
// Log.d("TAG", "checkGroupVisibility: lock testing 3:"+string)
return show
}
The exact error is coming when evaluating inspectionReportCarParList (i.e. the first query in the code). Here is the full stacktrace :
android.database.CursorWindowAllocationException: Could not allocate CursorWindow '/data/user/0/com.example.visor/databases/report.json-db' of size 104857600 due to error -12.
at android.database.CursorWindow.nativeCreate(CursorWindow.java)
at android.database.CursorWindow.<init>(CursorWindow.java:139)
at android.database.CursorWindow.<init>(CursorWindow.java:120)
at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:202)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:149)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:142)
at de.greenrobot.dao.AbstractDao.loadAllFromCursor(AbstractDao.java:371)
at de.greenrobot.dao.AbstractDao.loadAllAndCloseCursor(AbstractDao.java:184)
at de.greenrobot.dao.InternalQueryDaoAccess.loadAllAndCloseCursor(InternalQueryDaoAccess.java:21)
at de.greenrobot.dao.query.Query.list(Query.java:130)
at de.greenrobot.dao.query.QueryBuilder.list(QueryBuilder.java:353)
at com.example.inspectionreport.utils.ReportUtils.checkGroupVisibility(ReportUtils.kt:31)
Also I am using de.greenrobot:greendao:2.0.0 this version of greendao.
I thought greendao is supposed to handle all the cusrsor actions and it closes the cursor after querying itself. But still cursorWindow size is getting very huge and the application crashes. Please help!
A Cursor Window has a restricted size (depends upon the Android Version but up to 4Mb). 104857600 is 100Mb, so way too large.
A CursorWindow has to be able to accommodate 1 or more rows, if it cannot hold 1 row then you will get such an error.
It is possible to store data that is too large to be retrieved (it is a common issue with images).
The recommended way of handling such large amounts of data is to store the data, such as an image, in a file and store the path or part of the path in the database.
Additional re the comment
The issue is not limited to multimedia, that is just an example of the data being too large. It could be String (TEXT) data.
Here's an example that shows the case (just using SQLite which greenDao is basically just a wrapper around), the example also includes an example of an alternative that does not experience the issue as it stores managable sections of the details of the report in a separate related table.
Consider the following code:-
So there are 5 stages each progressively inserting close to 1Mb of textual data along the lines of :-
....
Each stage inserts the same data (1Mb,2Mb .... 5Mb) twice.
When run, using App Inspection, then:-
If an attempt is made to read all of the data in the v1_report table then the CursorWindow size occurs:-
Now for v2_report, there is no issue :-
As the long textual data has been split and placed into the v2_details table :-
The issue can be clearly seeing (also proving that the data exists and has been inserted successfully into v1_report) by using the following:-
Although not accurate (the example has been quickly put together and it looks as though I've dropped a byte/character) the equivalent can be extracted from both the v2 tables as per:-