{"record":{"id":"f564a16702c68e72","repo":"greenrobot/greenDAO","slug":"this-config-tablename-does-not-have-a-sing","errorCode":null,"errorMessage":"${this} (${config.tablename}) does not have a single-column primary key","messagePattern":"(.+?) \\((.+?)\\) does not have a single-column primary key","errorType":"exception","errorClass":"DaoException","httpStatus":null,"severity":"error","filePath":"DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java","lineNumber":917,"sourceCode":"            }\n        }\n        if (txEx != null) {\n            throw txEx;\n        }\n    }\n\n    /**\n     * Updates the given entities in the database using a transaction.\n     *\n     * @param entities The entities to update.\n     */\n    public void updateInTx(T... entities) {\n        updateInTx(Arrays.asList(entities));\n    }\n\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;","sourceCodeStart":899,"sourceCodeEnd":935,"githubUrl":"https://github.com/greenrobot/greenDAO/blob/0bbb338e17c4cf28aba5aae62d42f73f50186157/DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java#L899-L935","documentation":"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).","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before (composite key entity)\ndao.deleteAll(); // throws\n// after\nList<Thing> all = dao.queryBuilder().build().list();\ndao.deleteInTx(all); // works with composite keys","handlingStrategy":"validation","validationCode":"if (config.pkColumns.length != 1) {\n    // use queryBuilder/deleteInTx path instead of single-PK APIs\n}","typeGuard":null,"tryCatchPattern":"try {\n    dao.count();\n} catch (DaoException e) {\n    if (e.getMessage().contains(\"single-column primary key\")) {\n        long n = dao.queryBuilder().buildCount().count(); // PK-agnostic fallback\n    } else throw e;\n}","preventionTips":["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."],"tags":["database","greendao","primary-key","composite-key"],"backgroundTag":"unsupported-operation","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"}