greenrobot/greenDAO · error · DaoException

Cannot delete entity, key is null

Error message

Cannot delete entity, key is null

What it means

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.

Solutions

  1. Check that the key is non-null before calling deleteByKey/deleteInTx.
  2. Load the entity first (or use delete(entity) with a managed entity) to obtain a valid key.
  3. Filter null keys out of the collection passed to deleteInTx.
  4. Insert the entity first so the DB assigns an autoincrement key before deleting.

Example fix

// before
userDao.deleteByKey(userId); // userId may be null
// after
if (userId != null) {
    userDao.deleteByKey(userId);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (key == null) { throw new IllegalArgumentException("Cannot delete: key is null"); }

Type guard

boolean isDeletable(K key) { return key != null; }

Try / catch

try {
    userDao.deleteByKey(key);
} catch (DaoException e) {
    if (e.getMessage().startsWith("Cannot delete entity, key is null")) {
        // nothing to delete; log and continue
    } else throw e;
}

Prevention

When it happens

Trigger: Calling deleteByKey(null), or deleteInTx()/deleteInTxInternal with a key collection containing null entries.

Common situations: 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.

Related errors


AI-assisted analysis of greenrobot/greenDAO@0bbb338e17 (2026-09-08). Data as JSON: /api/errors/a836deb6fa1a9d86. Report an issue: GitHub.

Appendix: source

Thrown at DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java:658

            try {
                synchronized (stmt) {
                    deleteByKeyInsideSynchronized(key, stmt);
                }
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
        }
        if (identityScope != null) {
            identityScope.remove(key);
        }
    }

    private void deleteByKeyInsideSynchronized(K key, DatabaseStatement stmt) {
        if (key instanceof Long) {
            stmt.bindLong(1, (Long) key);
        } else if (key == null) {
            throw new DaoException("Cannot delete entity, key is null");
        } else {
            stmt.bindString(1, key.toString());
        }
        stmt.execute();
    }

    private void deleteInTxInternal(Iterable<T> entities, Iterable<K> keys) {
        assertSinglePk();
        DatabaseStatement stmt = statements.getDeleteStatement();
        List<K> keysToRemoveFromIdentityScope = null;
        db.beginTransaction();
        try {
            synchronized (stmt) {
                if (identityScope != null) {
                    identityScope.lock();
                    keysToRemoveFromIdentityScope = new ArrayList<K>();
                }
                try {

View on GitHub (pinned to 0bbb338e17)