{"record":{"id":"4f3dcf48c8c806dd","repo":"greenrobot/greenDAO","slug":"entity-may-not-be-null","errorCode":null,"errorMessage":"Entity may not be null","messagePattern":"Entity may not be null","errorType":"validation","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java","lineNumber":930,"sourceCode":"        updateInTx(Arrays.asList(entities));\n    }\n\n    protected void assertSinglePk() {\n        if (config.pkColumns.length != 1) {\n            throw new DaoException(this + \" (\" + config.tablename + \") does not have a single-column primary key\");\n        }\n    }\n\n    public long count() {\n        return statements.getCountStatement().simpleQueryForLong();\n    }\n\n    /** See {@link #getKey(Object)}, but guarantees that the returned key is never null (throws if null). */\n    protected K getKeyVerified(T entity) {\n        K key = getKey(entity);\n        if (key == null) {\n            if (entity == null) {\n                throw new NullPointerException(\"Entity may not be null\");\n            } else {\n                throw new DaoException(\"Entity has no key\");\n            }\n        } else {\n            return key;\n        }\n    }\n\n    /**\n     * The returned RxDao is a special DAO that let's you interact with Rx Observables without any Scheduler set\n     * for subscribeOn.\n     *\n     * @see #rx()\n     */\n    @Experimental\n    public RxDao<T, K> rxPlain() {\n        if (rxDaoPlain == null) {\n            rxDaoPlain = new RxDao<>(this);","sourceCodeStart":912,"sourceCodeEnd":948,"githubUrl":"https://github.com/greenrobot/greenDAO/blob/0bbb338e17c4cf28aba5aae62d42f73f50186157/DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java#L912-L948","documentation":"getKeyVerified() guarantees a non-null key: if the passed entity itself is null, getKey(entity) is null and greenDAO throws NullPointerException with 'Entity may not be null'. This is a guard against passing a null entity into key-sensitive operations.","triggerScenarios":"Calling getKeyVerified(null), or internal update/delete paths that pass a null entity (e.g. updateInTx collections containing null).","commonSituations":"Collections built from optional lookups (map.get() returned null) then handed to insertInTx/updateInTx; cursors or joins producing null rows passed to the DAO.","solutions":["Null-check the entity before any DAO call.","Filter nulls from collections before batch transactions.","Return an Optional/null-safe result from the lookup that produced the entity.","Throw early with a descriptive application-level message."],"exampleFix":"// before\nuserDao.update(maybeUser); // maybeUser can be null\n// after\nif (maybeUser != null) {\n    userDao.update(maybeUser);\n}","handlingStrategy":"type-guard","validationCode":"if (entity == null) return; // or throw an app-level IllegalArgumentException","typeGuard":"boolean isValidEntity(T e) { return e != null; }","tryCatchPattern":"try {\n    T key = dao.getKeyVerified(entity);\n} catch (NullPointerException e) {\n    if (\"Entity may not be null\".equals(e.getMessage())) {\n        // caller bug: null entity passed; log and fix call site\n    } else throw e;\n}","preventionTips":["Null-check entities at API boundaries before DAO calls.","Filter nulls from collections before batch transactions.","Make lookups return Optional-style results instead of null entities.","Fail fast in your own layer with descriptive messages."],"tags":["database","greendao","null-entity","null-check"],"backgroundTag":"null-argument","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"}