{"record":{"id":"de45e090ad3a14a5","repo":"greenrobot/greenDAO","slug":"cannot-update-entity-without-key-was-it-inserted","errorCode":null,"errorMessage":"Cannot update entity without key - was it inserted before?","messagePattern":"Cannot update entity without key - was it inserted before\\?","errorType":"exception","errorClass":"DaoException","httpStatus":null,"severity":"error","filePath":"DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java","lineNumber":804,"sourceCode":"            } finally {\n                db.endTransaction();\n            }\n        }\n    }\n\n    public QueryBuilder<T> queryBuilder() {\n        return QueryBuilder.internalCreate(this);\n    }\n\n    protected void updateInsideSynchronized(T entity, DatabaseStatement stmt, boolean lock) {\n        // To do? Check if it's worth not to bind PKs here (performance).\n        bindValues(stmt, entity);\n        int index = config.allColumns.length + 1;\n        K key = getKey(entity);\n        if (key instanceof Long) {\n            stmt.bindLong(index, (Long) key);\n        } else if (key == null) {\n            throw new DaoException(\"Cannot update entity without key - was it inserted before?\");\n        } else {\n            stmt.bindString(index, key.toString());\n        }\n        stmt.execute();\n        attachEntity(key, entity, lock);\n    }\n\n    protected void updateInsideSynchronized(T entity, SQLiteStatement stmt, boolean lock) {\n        // To do? Check if it's worth not to bind PKs here (performance).\n        bindValues(stmt, entity);\n        int index = config.allColumns.length + 1;\n        K key = getKey(entity);\n        if (key instanceof Long) {\n            stmt.bindLong(index, (Long) key);\n        } else if (key == null) {\n            throw new DaoException(\"Cannot update entity without key - was it inserted before?\");\n        } else {\n            stmt.bindString(index, key.toString());","sourceCodeStart":786,"sourceCodeEnd":822,"githubUrl":"https://github.com/greenrobot/greenDAO/blob/0bbb338e17c4cf28aba5aae62d42f73f50186157/DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java#L786-L822","documentation":"update() executes a prepared UPDATE statement that binds the entity's primary key in the WHERE clause. If getKey(entity) returns null, there is no key to bind and greenDAO throws DaoException — the entity was likely never inserted, so it cannot be updated.","triggerScenarios":"Calling update(entity) or updateInsideSynchronized with an entity whose primary key field is null — typically a freshly constructed object never inserted via insert().","commonSituations":"Creating a new entity and calling update instead of insert; an entity deserialized/copied without its id; resetting the id field to null before update; using updateInTx with un-persisted objects.","solutions":["Call insert(entity) first so the DB assigns a key, then update.","Use insertOrUpdate(entity) to handle both cases.","Check getKey(entity) != null before updating.","Generate/assign the primary key manually before update if the schema allows it."],"exampleFix":"// before\nUser u = new User(\"alice\");\nuserDao.update(u); // throws: no key\n// after\nUser u = new User(\"alice\");\nuserDao.insert(u); // assigns key\nu.setName(\"alice2\");\nuserDao.update(u);","handlingStrategy":"validation","validationCode":"if (userDao.getKey(entity) == null) {\n    userDao.insert(entity);\n} else {\n    userDao.update(entity);\n}","typeGuard":"boolean isPersisted(T e) { return dao.getKey(e) != null; }","tryCatchPattern":"try {\n    userDao.update(entity);\n} catch (DaoException e) {\n    if (e.getMessage().contains(\"without key\")) {\n        userDao.insertOrUpdate(entity);\n    } else throw e;\n}","preventionTips":["Use insertOrUpdate()/save() when unsure whether an entity exists.","Never null out primary key fields after loading.","Validate getKey(entity) before update calls.","Distinguish DTOs (new objects) from managed entities in your code."],"tags":["database","greendao","null-key","update"],"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"}