{"record":{"id":"ff4380786bd71a13","repo":"greenrobot/greenDAO","slug":"entity-has-no-key","errorCode":null,"errorMessage":"Entity has no key","messagePattern":"Entity has no key","errorType":"exception","errorClass":"DaoException","httpStatus":null,"severity":"error","filePath":"DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java","lineNumber":932,"sourceCode":"\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);\n        }\n        return rxDaoPlain;","sourceCodeStart":914,"sourceCodeEnd":950,"githubUrl":"https://github.com/greenrobot/greenDAO/blob/0bbb338e17c4cf28aba5aae62d42f73f50186157/DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java#L914-L950","documentation":"getKeyVerified() found the entity non-null but getKey(entity) returned null, meaning the entity has no primary key assigned. greenDAO throws DaoException('Entity has no key') because callers of getKeyVerified require a guaranteed key.","triggerScenarios":"Calling getKeyVerified(entity) (directly or via update/delete internals) on a non-null entity whose @Id field is still null — i.e., never inserted.","commonSituations":"Updating or deleting freshly constructed/un-persisted entities; entities copied without id; entities deserialized from JSON/backups lacking the key field.","solutions":["insert(entity) first so the key is assigned before key-required operations.","Use insertOrUpdate for upsert semantics.","Check dao.getKey(entity) != null before proceeding.","Assign the primary key manually if the schema permits (non-autoincrement)."],"exampleFix":"// before\nif (dao.getKeyVerified(user) != null) { ... } // throws if not inserted\n// after\nK key = dao.getKey(user);\nif (key == null) {\n    userDao.insert(user);\n    key = dao.getKey(user);\n}","handlingStrategy":"validation","validationCode":"K key = dao.getKey(entity);\nif (key == null) { dao.insert(entity); key = dao.getKey(entity); }","typeGuard":"boolean hasKey(T e) { return e != null && dao.getKey(e) != null; }","tryCatchPattern":"try {\n    K key = dao.getKeyVerified(entity);\n} catch (DaoException e) {\n    if (\"Entity has no key\".equals(e.getMessage())) {\n        dao.insert(entity); // assign key, retry\n    } else throw e;\n}","preventionTips":["Always insert before update/delete on fresh entities.","Use insertOrUpdate for upsert semantics.","Never strip the id field when copying/serializing entities.","Check getKey() before key-required operations."],"tags":["database","greendao","null-key","unpersisted-entity"],"backgroundTag":"entity-not-found","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"}