{"record":{"id":"a836deb6fa1a9d86","repo":"greenrobot/greenDAO","slug":"cannot-delete-entity-key-is-null","errorCode":null,"errorMessage":"Cannot delete entity, key is null","messagePattern":"Cannot delete entity, key is null","errorType":"exception","errorClass":"DaoException","httpStatus":null,"severity":"error","filePath":"DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java","lineNumber":658,"sourceCode":"            try {\n                synchronized (stmt) {\n                    deleteByKeyInsideSynchronized(key, stmt);\n                }\n                db.setTransactionSuccessful();\n            } finally {\n                db.endTransaction();\n            }\n        }\n        if (identityScope != null) {\n            identityScope.remove(key);\n        }\n    }\n\n    private void deleteByKeyInsideSynchronized(K key, DatabaseStatement stmt) {\n        if (key instanceof Long) {\n            stmt.bindLong(1, (Long) key);\n        } else if (key == null) {\n            throw new DaoException(\"Cannot delete entity, key is null\");\n        } else {\n            stmt.bindString(1, key.toString());\n        }\n        stmt.execute();\n    }\n\n    private void deleteInTxInternal(Iterable<T> entities, Iterable<K> keys) {\n        assertSinglePk();\n        DatabaseStatement stmt = statements.getDeleteStatement();\n        List<K> keysToRemoveFromIdentityScope = null;\n        db.beginTransaction();\n        try {\n            synchronized (stmt) {\n                if (identityScope != null) {\n                    identityScope.lock();\n                    keysToRemoveFromIdentityScope = new ArrayList<K>();\n                }\n                try {","sourceCodeStart":640,"sourceCodeEnd":676,"githubUrl":"https://github.com/greenrobot/greenDAO/blob/0bbb338e17c4cf28aba5aae62d42f73f50186157/DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java#L640-L676","documentation":"deleteByKey/deleteInTx must bind the primary key to the DELETE statement. When the key object is null, the statement cannot be built and greenDAO throws DaoException instead of silently doing nothing. Every entity to delete must have its primary key set.","triggerScenarios":"Calling deleteByKey(null), or deleteInTx()/deleteInTxInternal with a key collection containing null entries.","commonSituations":"Passing a key read from a detached/never-inserted entity whose id was never assigned; an entity object whose key getter returned null because fields were cleared after load; collections built from maps where a lookup returned null.","solutions":["Check that the key is non-null before calling deleteByKey/deleteInTx.","Load the entity first (or use delete(entity) with a managed entity) to obtain a valid key.","Filter null keys out of the collection passed to deleteInTx.","Insert the entity first so the DB assigns an autoincrement key before deleting."],"exampleFix":"// before\nuserDao.deleteByKey(userId); // userId may be null\n// after\nif (userId != null) {\n    userDao.deleteByKey(userId);\n}","handlingStrategy":"type-guard","validationCode":"if (key == null) { throw new IllegalArgumentException(\"Cannot delete: key is null\"); }","typeGuard":"boolean isDeletable(K key) { return key != null; }","tryCatchPattern":"try {\n    userDao.deleteByKey(key);\n} catch (DaoException e) {\n    if (e.getMessage().startsWith(\"Cannot delete entity, key is null\")) {\n        // nothing to delete; log and continue\n    } else throw e;\n}","preventionTips":["Never call deleteByKey with values from nullable lookups without checking.","Filter nulls from key collections before deleteInTx.","Assign keys via insert() before attempting delete operations."],"tags":["database","greendao","null-key","delete"],"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"}