{"record":{"id":"118b1fce7c34fa51","repo":"greenrobot/greenDAO","slug":"this-operation-only-works-with-cached-lazy-lists","errorCode":null,"errorMessage":"This operation only works with cached lazy lists","messagePattern":"This operation only works with cached lazy lists","errorType":"exception","errorClass":"DaoException","httpStatus":null,"severity":"error","filePath":"DaoCore/src/main/java/org/greenrobot/greendao/query/LazyList.java","lineNumber":162,"sourceCode":"        if (size == 0) {\n            cursor.close();\n        }\n\n        lock = new ReentrantLock();\n    }\n\n    /** Loads the remaining entities (if any) that were not loaded before. Applies to cached lazy lists only. */\n    public void loadRemaining() {\n        checkCached();\n        int size = entities.size();\n        for (int i = 0; i < size; i++) {\n            get(i);\n        }\n    }\n\n    protected void checkCached() {\n        if (entities == null) {\n            throw new DaoException(\"This operation only works with cached lazy lists\");\n        }\n    }\n\n    /** Like get but does not load the entity if it was not loaded before. */\n    public E peek(int location) {\n        if (entities != null) {\n            return entities.get(location);\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    /** Closes the underlying cursor: do not try to get entities not loaded (using get) before. */\n    public void close() {\n        cursor.close();\n    }\n","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/greenrobot/greenDAO/blob/0bbb338e17c4cf28aba5aae62d42f73f50186157/DaoCore/src/main/java/org/greenrobot/greendao/query/LazyList.java#L144-L180","documentation":"greenDAO's LazyList can operate in two modes: with an eagerly-loaded entity cache (entities != null) or fully lazy, backed only by the cursor. Operations like loadRemaining() and subList() require random access to already-loaded entities, so they throw this DaoException when the list was created without caching. The check is a guard in LazyList.checkCached() protecting operations that cannot be satisfied lazily.","triggerScenarios":"Calling loadRemaining() or subList() on a LazyList obtained from a query that was not built with caching — i.e. Query.forCurrentThread(...)/lazyList() where the query does not use setForThread/CACHED variant (entities == null).","commonSituations":"Developers grab lazyList() for memory efficiency, then call subList() or loadRemaining() expecting List semantics; it fails because the lazy list never materializes entities into the backing array.","solutions":["Use the cached list: call query.list() (or lazyList() only when you truly stream via iterator) instead of calling subList/loadRemaining on the lazy list.","If you need partial loading with caching, iterate with get()/peek() on the LazyList instead of subList().","Copy needed items into a plain ArrayList by iterating the LazyList, then use subList on that copy."],"exampleFix":"// before\nLazyList<User> lazy = query.listLazy();\nList<User> page = lazy.subList(10, 20); // DaoException\n// after\nList<User> all = query.list();\nList<User> page = all.subList(10, 20);","handlingStrategy":"fallback","validationCode":"LazyList<User> l = query.listLazyUncached();\nboolean ok = !(needsSubList || needsLoadRemaining); // avoid these ops on uncached lazy lists","typeGuard":null,"tryCatchPattern":"try { page = lazyList.subList(from, to); } catch (DaoException e) { page = query.list().subList(from, to); }","preventionTips":["Use query.list() when you need List operations (subList, random access).","Reserve listLazy()/listLazyUncached() for iteration/streaming only.","Read the LazyList javadoc: subList/loadRemaining require the cached variant."],"tags":["greendao","lazylist","android","database"],"backgroundTag":"unsupported-operation","analyzedSha":"0bbb338e17c4cf28aba5aae62d42f73f50186157","analyzedAt":"2026-09-08T03:22:36.050Z","contentChangedAt":"2026-09-08T03:22:36.050Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}