greenrobot/greenDAO · error · DaoException
( ) does not have a single-column primary key
Error message
${this} (${config.tablename}) does not have a single-column primary key What it means
Several greenDAO operations (deleteAll, count-by-key helpers, key-array based queries) only support entities with exactly one primary-key column. assertSinglePk() throws DaoException when config.pkColumns.length != 1 (zero or composite keys).
Solutions
- Give the entity a single-column primary key (annotate one field with @Id) and regenerate DAOs.
- Avoid single-PK-only APIs on composite-key entities; use queryBuilder/deleteInTx instead.
- For no-PK entities, add an autoincrement id column via migration.
- Wrap the call in a check of config.pkColumns length in custom DAO code.
Example fix
// before (composite key entity) dao.deleteAll(); // throws // after List<Thing> all = dao.queryBuilder().build().list(); dao.deleteInTx(all); // works with composite keys
Defensive patterns
Strategy: validation
Validate before calling
if (config.pkColumns.length != 1) {
// use queryBuilder/deleteInTx path instead of single-PK APIs
} Try / catch
try {
dao.count();
} catch (DaoException e) {
if (e.getMessage().contains("single-column primary key")) {
long n = dao.queryBuilder().buildCount().count(); // PK-agnostic fallback
} else throw e;
} Prevention
- Give every entity a single-column @Id primary key.
- For legacy composite-key tables, add a surrogate id column.
- Know which greenDAO APIs require single PK (count, deleteAll, key-array queries).
- Prefer queryBuilder-based operations for composite-key entities.
When it happens
Trigger: Calling count(), deleteAll(), or key-based helpers on a DAO whose entity uses a composite primary key or has no primary key at all (allColumns != pkColumns).
Common situations: Generated entity with @Id plus an additional @Unique composite expectation; legacy tables with composite PKs; entities where no @Id was declared so pkColumns is empty.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Expected unique result, but count was
- Cannot delete entity, key is null
- Entity does not exist in the database anymore
- Cannot update entity without key - was it inserted before?
- Entity may not be null
AI-assisted analysis of greenrobot/greenDAO@0bbb338e17 (2026-09-08).
Data as JSON: /api/errors/f564a16702c68e72.
Report an issue: GitHub.
Appendix: source
Thrown at DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java:917
}
}
if (txEx != null) {
throw txEx;
}
}
/**
* Updates the given entities in the database using a transaction.
*
* @param entities The entities to update.
*/
public void updateInTx(T... entities) {
updateInTx(Arrays.asList(entities));
}
protected void assertSinglePk() {
if (config.pkColumns.length != 1) {
throw new DaoException(this + " (" + config.tablename + ") does not have a single-column primary key");
}
}
public long count() {
return statements.getCountStatement().simpleQueryForLong();
}
/** See {@link #getKey(Object)}, but guarantees that the returned key is never null (throws if null). */
protected K getKeyVerified(T entity) {
K key = getKey(entity);
if (key == null) {
if (entity == null) {
throw new NullPointerException("Entity may not be null");
} else {
throw new DaoException("Entity has no key");
}
} else {
return key;View on GitHub (pinned to 0bbb338e17)